Trouble replacing text in files

I am working on this script to remove certain text from a path of files.

It collects all of the files that contain the text into an array, but my attempt to replace that text with blank space fails. Here is the script:

$Path = "C:\Temp\ITScriptForOthers"
$Text = "sometext"
$PathArray = @()

# This code snippet gets all the files in the Path that contain -Filter in the filename
Get-ChildItem -Path "C:\Temp\ITScriptForOthers" -Recurse -Filter *sometext*.* | 
        select -ExpandProperty Fullname | Out-File -Append c:\temp\itscript\logs\report.txt

# This code snippet gets all the files in $Path that contain $Text
Get-ChildItem $Path -Filter "*.*" -Recurse |

ForEach-Object {
If (Get-Content $_.FullName | Select-String -Pattern $Text) {
$PathArray += $_.FullName
#My attempt to replace the $Text with blank space ''
ForEach-Object { Get-Content "$PathArray.FullName" {$_.FullName -replace "$Text",''} }

$PathArray | ForEach-Object {$_} | Out-File -Append c:\temp\itscript\logs\report.txt

The output in Report.txt looks like this:

C:\Temp\ITScriptForOthers\Logs\New Text DocumentSomeText.txt
C:\Temp\ITScriptForOthers\CheckCerts\New Text Document.txt

The text in question is in each of those files, but it never gets deleted.

Obviously the magic is in this line, or something like it:

ForEach-Object { Get-Content "$PathArray.FullName" {$_.FullName -replace "$Text",''} }

Thanks for any help.


Can you explain what you intent this to do ?

If you are replacing file name Get-Content is not required, its used to read the content of files and just noticed "$PathArray.FullName". When you select property of an object, here "$PathArray you can’t wrap it in double quotes and if you want to wrap it should be made as a sub expression like "$($PathArray.FullName)" or not use double quotes at all.

Hello Prasoon,
I wanted that line of code to go through each element of the array, which is a bunch of paths to files, and replace the “$Text” with ‘’. I basically want to remove that text from all of the files.

Thank You.

So you are trying to rename the path to the files in your list. An example will be like below

Get-ChildItem -Path "C:\Temp\ITScriptForOthers" | Foreach-Object -Process {
   if($_.parent -match '<string to match>'){
        $_.Parent -replace <string to match>,<new string>

I am actually trying to delete the txt string from all of the files it was found in. The array contains all of the files and paths that has the string I need deleted.

The code you posted does not work (probably because I did not explain what Im trying to do so well).

I tried tweaking it slightly like so:

Get-ChildItem -Path "C:\Temp\ITScriptForOthers" -Recurse | Get-Content | Foreach-Object -Process {
   if($_.parent -match 'sometext'){
        $_.Parent -replace "sometext",""

But I am still not having luck.

Get-Content is to read the contents of a file and you don’t need it unless you want to read the file contents and do something.

To make it clear
Are you modifying file path or file contents ?

1 Like

I am trying to modify the contents of the files

ok so I was not happy with that version of the script, so found a different one, that I slightly modified to fit my needs. The problem is, it deletes the text from the files, but it only deletes the text if it is starting a line, it does not get deleted if the text has any characters before it in the file. Anyway to tweak this so it deletes ALL instances of the text in the files?

$FileDir     = "C:\Temp\ITScriptForOthers"
$MatchString = "SomeText"

$Files = @(Get-ChildItem -Path $FileDir -Recurse -Filter *.ps1)

foreach( $File in $Files ){
    $Reader     = New-Object -TypeName System.IO.StreamReader -ArgumentList $File.FullName
    $NewContent = New-Object -TypeName System.Collections.ArrayList

   $MatchFound   = $false
    $PreviousLine = $null

   while( -not $Reader.EndOfStream ){
        $Line = $Reader.ReadLine()

       if( $MatchFound ){
            $MatchFound = $false

       if( $Line -eq $MatchString ){
            $MatchFound   = $true
            $PreviousLine = $null
            $null = $NewContent.Add($PreviousLine)
            $PreviousLine = $Line

   $null = $NewContent.Add($PreviousLine)

   $NewContent |
        Where-Object { $_ -ne $null } |
        Out-File -FilePath $File.FullName -Force

As always, Thank You.

Wow, what a mess. Do you understand what this code does? :smirk: I’d recommend not to use code you don’t understand. Instead you should make a big step back and start new from scratch.

It might not be the most sophisticated code but it should do the trick, is hopefully easy to understand and of course you can improve if you need.

$FileDir     = 'C:\Temp\ITScriptForOthers'
$MatchString = 'SomeText'

Get-ChildItem -Path $FileDir -Filter *.txt -Recurse |
    ForEach-Object {
        $NewContent = 
        (Get-Content -Path $_.FullName |
            ForEach-Object {
                $_ -replace $MatchString
        $NewContent | Out-File -FilePath $_.FullName -Force

It looks for *.txt files in the folder specified in $FileDir. Reads the content of all of those files and replaces all occurences of the pattern specified in $MatchString on all lines of each file. The result will overwrite the original file.

The -replace operator works with regex. So if you have special characters in your $MatchString you need to escape them.

Please test this code with test data to be able to fix it if something is not as expected!!! :point_up_2:t4:

Thanks Olaf, I will try try this for sure.

I understand what you are saying, I was using test data when I was using the last script, as I understood it was deleting the files and recreating them. In my tweaks and testing a few times it completely wiped out my test files :wink: but I was kind of expecting that to happen.

I consider that part of the learning process :slight_smile:


Your script works great Olaf. I will study those techniques for future use :clap: