Reputation: 361
So, i need to save a string that was replaced on files.
I'm doing something wrong, but i`m not be able to figure it out, what!
My code:
Get-ChildItem -Path C:\Users\user\Documents -Recurse -Include "*.txt" -File | Select-String -Pattern \b192\.168\.10\.2\b , \b192\.168\.10\.11\b -AllMatches -List | Foreach-Object { $_ -replace '\b192\.168\.10\.2\b', "DEV" -and $_ -replace '\b192\.168\.10\.11\b', "QUAL" | Set-Content $_}
And gives-me the following error:
Set-Content : Could not open the alternate data stream '1:192.168.10.11' of the file 'C:\Users\user\Documents\result.txt'.
At line:1 char:323
+ ... place '\b192\.168\.10\.11\b', "QUAL" | Set-Content $_}
+
+ CategoryInfo : ObjectNotFound: (C:\Users\paulo....ents\result.txt:String) [Set-Content], FileNotFoundException
+ FullyQualifiedErrorId : GetContentWriterFileNotFoundError,Microsoft.PowerShell.Commands.SetContentCommand
Set-Content : Could not open the alternate data stream '1:192.168.10.11' of the file
'C:\Users\user\Documents\test.txt'
At line:1 char:323 ... place '\b192\.168\.10\.11\b', "QUAL" | Set-Content $_}
CategoryInfo : ObjectNotFound: (C:\Users\user\test.txt:String) [Set-Content], FileNotFoundException
FullyQualifiedErrorId : GetContentWriterFileNotFoundError,Microsoft.PowerShell.Commands.SetContentCommand
Thanks for any Help!
Upvotes: 1
Views: 395
Reputation: 61068
The -and
operator is used inside if
tests like if(this -and that)
.
You should change the double replace actions from
$_ -replace '\b192\.168\.10\.2\b', "DEV" -and $_ -replace '\b192\.168\.10\.11\b', "QUAL"
into
$_ -replace '\b192\.168\.10\.2\b', "DEV" -replace '\b192\.168\.10\.11\b', "QUAL"
Also, if I understand the question properly, you want to find all string replacements in the file, and to get all, you need to remove the -List
switch from Select-String.
Next, as Mathias explains in his answer, you need to use the Path
property from the current match to get the file FullName.
However, if you pipe this through to Set-Content straight away, you will get an exception because the file then is in use and you cannot write to the same file.
Below creates a new file in the same path, with _replacements
appended to the filename
# use '-Include' instead of '-Filter' if you need more file extensions to filter on
Get-ChildItem -Path 'C:\Users\user\Documents' -Recurse -Filter "*.txt" -File |
Select-String -Pattern '\b192\.168\.10\.2\b', '\b192\.168\.10\.11\b' -AllMatches |
Foreach-Object {
$file = '{0}_replacements{1}' -f [System.IO.Path]::GetFileNameWithoutExtension($_.Path),
[System.IO.Path]::GetExtension($_.Path)
$target = Join-Path -Path ([System.IO.Path]::GetDirectoryName($_.Path)) -ChildPath $file
$_ -replace '\b192\.168\.10\.2\b', "DEV" -replace '\b192\.168\.10\.11\b', "QUAL" |
Add-Content -Path $target
}
This results in a file called 'C:\Users\user\Documents\test_replacements.txt'
C:\Users\user\Documents\test.txt:4:DEV C:\Users\user\Documents\test.txt:7:QUAL
The original file 'C:\Users\user\Documents\test.txt' will not be altered.
Upvotes: 2
Reputation: 174485
Inside the ForEach-Object
block, $_
will refer to the current match result as returned by Select-String
- to get the file path, reference the Path
property:
... | ForEach-Object { ... |Set-Content -LiteralPath $_.Path}
Upvotes: 2