You don't need multiple ForEach-Object
loops. For implementing -type f
you need to filter for files, though. In PowerShell v3 and newer you'd do that with the parameter -File
. In earlier versions you'd have to add a Where-Object {$_.PSIsContainer}
to the pipeline.
Something like this should do what you want:
Get-ChildItem -Recurse -File | ForEach-Object {
(Get-Content $_.FullName) -replace 'string1', 'string2' |
Set-Content $_.FullName
$_.FullName
}
or (for short):
ls -r -File | %{(gc $_.FullName) -replace 'string1', 'string2' | sc $_.FullName; $_.FullName}
Note that Set-Content
automatically saves the file with ASCII encoding (well, technically it's an ANSI encoding, but let's ignore that since Microsoft has the bad habit of using the two terms synonymous anyway), so you may need to specify a different encoding if you don't want that.
Note also that if you have non-text files you may want to exclude them from processing, since Get-Content
and Set-Content
do specific things when reading/writing files that are undesirable for binary files (Get-Content
without the parameter -Raw
or -Encoding Byte
splits the input at newlines, Set-Content
appends a newline (CR-LF) to the end of each input string before writing them to the output file).