user2628187
user2628187

Reputation: 307

Search and replace with PowerShell

I'm using the below PowerShell script to search and replace, which works fine.

$files = Get-ChildItem 'E:\replacetest' -Include "*.txt" -Recurse | ? {Test-Path $_.FullName -PathType Leaf}

foreach($file in $files)
{
    $content = Get-Content $file.FullName | Out-String
    $content| Foreach-Object{$_ -replace 'hello' , 'hellonew'`
                                -replace 'hola' , 'hellonew' } | Out-File $file.FullName -Encoding utf8
}

The issue is the script also modifies the files which does not have the matching text in it. How we ignore the files that do not have the matching text?

Upvotes: 3

Views: 1372

Answers (2)

Shawn Esterman
Shawn Esterman

Reputation: 2342

You can use match to see if the content is actually changed. Since you were always writing using out-file the file would be modified.

$files = Get-ChildItem 'E:\replacetest' -Include "*.txt" -Recurse | Where-Object {Test-Path $_.FullName -PathType Leaf}

foreach( $file in $files ) { 
    $content = Get-Content $file.FullName | Out-String
    if ( $content -match ' hello | hola ' ) {
        $content -replace ' hello ' , ' hellonew ' `
                 -replace ' hola ' , ' hellonew ' | Out-File $file.FullName -Encoding utf8
        Write-Host "Replaced text in file $($file.FullName)"
    }    
}

Upvotes: 3

Christopher G. Lewis
Christopher G. Lewis

Reputation: 4835

You've got an extra foreach and you need an if statement:

$files = Get-ChildItem 'E:\replacetest' -Include "*.txt" -Recurse | ? {Test-Path $_.FullName -PathType Leaf}

foreach($file in $files)
{ 
  $content = Get-Content $file.FullName | Out-String
  if ($content -match 'hello' -or $content -match 'hola') {
    $content -replace 'hello' , 'hellonew'`
            -replace 'hola' , 'hellonew' | Out-File $file.FullName -Encoding utf8    
  }
}

Upvotes: 1

Related Questions