I am trying to write an equivalent of
find -name "*.xml" | xargs grep -l "Search String"
| xargs perl -p -i -e 's/Search String/Replace String/g'
in powershell. This is what I came up with.
Get-ChildItem 'D:\code\cpp\FileHandlingCpp\input - Copy' -Recurse |
Select-String -SimpleMatch $src_str |
foreach{(Get-Content $_.path) | ForEach-Object { $_ -replace $src_str, $target_str }}
I get the error "The process cannot access the file because it is being used by another process”. So I came up with the multiple lines version as shown below. I am able to do in-replace of the strings now except the one in $src_str. What's wrong with $src_str ?
$src_str="<?xml version=""1.0"" encoding=""UTF-8"" standalone=""yes"" ?>"
$target_str=""
echo $src_str
foreach ($var in (Get-ChildItem 'D:\code\cpp\FileHandlingCpp\input - Copy' -Recurse
| Select-String -SimpleMatch $src_str).Path)
{
(Get-Content $var) | ForEach-Object { $_ -replace $src_str, $target_str }
| Set-Content $var
}
You can call the PowerShell replace method on any string to replace any literal string with another. If the string-to-be-replaced isn't found, the replace() method returns nothing. You don't need to assign a string to a variable to replace text in a string.
One way to do that is to use the Set-Content command. The Set-Content command replaces all contents of a file with assigning a new value. Whenever you now read the C:\file. txt file with Get-Content , you'll see that it now contains the new content.
In PowerShell we can use the Replace() method on any string or variable that is a string. The method needs two arguments, the text or character that you want to find and the with what you want to replace it with.
Maybe it would help to get back to your original goal of implementing the equivalent of the Unix version. Here is essentially the equivalent PowerShell version.
$search = '<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>'
$replace = 'test'
$dir = 'D:\code\cpp\FileHandlingCpp\input - Copy'
dir -Path $dir -Recurse -Filter *.xml | ForEach-Object {
(Get-Content -Path $_.FullName) -replace $search, $replace |
Set-Content $_.FullName
}
Note - watch out for text file encoding changes that may occur from re-writing the file. You can specify the output encoding if you need to using Set-Content
's -Encoding
parameter e.g. ASCII
.
This took me a while to figure out but I got it!
It's a one liner. Just go to the folder you want to start at and type this in. Change the file.name (use wild cards if you want) and string1 and string2 with the file name you want to search for and the string1 you want to replace with string2.
So this searches folders recursivly and for each file it replaces a string with another string and saves it. Basically Get-Childitem | ForEach-Object Replace and Save.
All set!
get-childitem -include file.name -Recurse | ForEach-Object { ( Get-Content -Path $_.FullName ) -replace 'string1', 'string2' | set-content $_.fullname }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With