Romz
Romz

Reputation: 1457

PowerShell Script to Find and Replace for all Files

I have many .cmd and .ps1 files in C:\Foo folder and subfolders, I need to replace the word "vanilla" with the word "chocolate" case insensitive in all files within that folder and subfolders.

This is how I do it:

Get-ChildItem C:\Foo *.cmd *.ps1 -recurse |
    Foreach-Object {
        $c = ($_ | Get-Content) 
        $c = $c -replace 'vanilla','chocolate'
        [IO.File]::WriteAllText($_.FullName, ($c -join "`r`n"))
    }

I use [IO.File]::WriteAllText only because Set-Content adds new line at the end (I don't get why though).

The issue is that it opens and writes to all files, even files that don't contain the word 'vanilla', and therefore modifies time stamp of all files. How do I improve the script so it WriteAllText only to files that has been changed by replace operation i.e. files that contain the word 'vanilla'?

Upvotes: 0

Views: 83

Answers (1)

Tony Hinkle
Tony Hinkle

Reputation: 4742

You just need an if statement to check if 'vanilla' exists in the file:

Get-ChildItem C:\Foo *.cmd *.ps1 -recurse |
    Foreach-Object {
        $c = ($_ | Get-Content) 
        if(($c -join "").contains("vanilla")){
            $c = $c -replace 'vanilla','chocolate'
            [IO.File]::WriteAllText($_.FullName, ($c -join "`r`n"))
        }
    }

Upvotes: 1

Related Questions