Mustafa Issa
Mustafa Issa

Reputation: 27

Why it doesn't change the content inside the file?

this code supposed to look for all demo.txt in the disk and change them from "demo" to "demodemo997182625" and then check if the file has changed or not

$found = 0;
$notfound = 0;


foreach ($file in Get-ChildItem -Path C:\ -Recurse -Filter demo.txt -ErrorAction SilentlyContinue )
{
  (Get-Content $file).Replace("demo","demo997182625") | Set-Content $file

   $x = (Get-Content $file).contain("demo997182625")


   if($x -eq $null){

  $found = 1 + $found;
  }

  else {

  $notfound = 1 + $notfound;
  
  }

}            
Write-Host "Changed" $found;
Write-Host "Not Changed" $notfound;



     

Upvotes: 0

Views: 78

Answers (1)

Theo
Theo

Reputation: 61158

A few remarks on your code:

  • the .Replace() and .Contains() string methods work case-sensitive, so .Replace("demo","demo997182625") won't find and replace "Demo". To have it work case-insensitively, use the -replace operator instead.
  • updated files can be reprocessed by Get-ChildItem, unless you have that part finish completely first. The easiest way to do that is by enclosing it between brackets
  • I would only save the file if there was something updated (i.e. the new value was found after -replace), otherwise leave it be
  • Get-ChildItem returns both FileInfo and DirectoryInfo objects. Since you are interested in changing files only, append the -File switch
  • best use the FullName property of the found file on the Get- and Set-Content cmdlets instead of the whole FileInfo object
$found = $notfound = 0

# surround the Get-ChildItem line with brackets, so it will finish before iterating on the result
# otherwise, it could reprocess files that were allready updated
foreach ($file in (Get-ChildItem -Path 'C:\' -Recurse -Filter 'demo.txt' -File -ErrorAction SilentlyContinue)) {
    # -replace uses regex, so surround the search string with '\b' boundary markers in order to do a whole-word search
    $content = (Get-Content -Path $file.FullName -Raw -Force) -replace '\bdemo\b', 'demo997182625'
    # test if the content now has the new value (again, use '\b' boundary markers)
    if ($content -match '\bdemo997182625\b') { 
        # save the updated file
        $content | Set-Content -Path $file.FullName -Force
        $found++ 
    } 
    else {$notfound++}

}            
Write-Host "Changed: $found"
Write-Host "Not Changed: $notfound"

P.S. If your search string contains characters that in regex have special meaning (see table below), you need to escape these with a backslash when using regex operators -replace and -match.

Special Characters in Regex

Char Description Meaning
\ Backslash Used to escape a special character
^ Caret Beginning of a string
$ Dollar sign End of a string
. Period or dot Matches any single character
| Vertical bar or pipe symbol Matches previous OR next character/group
? Question mark Match zero or one of the previous
* Asterisk or star Match zero, one or more of the previous
+ Plus sign Match one or more of the previous
( ) Opening and closing parenthesis Group characters
[ ] Opening and closing square bracket Matches a range of characters
{ } Opening and closing curly brace Matches a specified number of occurrences of the previous

Upvotes: 1

Related Questions