Reputation: 1457
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
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