Reputation: 942
Suppose we have a file foo.txt:
abc
abc
abc
And I want to turn it into:
abc
abc
HelloWorld
This command should work:
(gc foo.txt -Raw) -replace '(.*)abc', '$1HelloWorld' | Out-File foo.txt
Because I'm using -Raw switch, which reads the entire file instead of one line at a time. Then, the greedy pattern (.*) should match everything up to the last "abc" and replace it with "HelloWorld".
But it doesn't work. All 3 occurences of "abc" are replaced with "HelloWorld", as if "-replace" was processing the file one line at a time, despite the -Raw switch.
Why?
Upvotes: 1
Views: 1529
Reputation: 4428
You have to include the single line mode modifier (?s)
like so:
(gc foo.txt -Raw) -replace '(?s)(.*)abc', '$1HelloWorld' | Out-File foo.txt
Without it, the .
will not match carriage returns and line feeds.
Upvotes: 2
Reputation: 8978
I'm breaking PS to multiple lines for sake of simplicity. I'm replacing sed
with TEMPOR
Try:
$rx = '(?is)(.*)sed(.*)' ## Search for last occurance of sed.
$replacement = '$1TEMPOR$2' ## Replace sed with TEMPOR
(Get-Content -Path d:\data.txt -Raw) -ireplace $rx, $replacement | Out-File d:\test.txt
Content of data.txt:
A nulla odio aptent metus,
mattis mattis elementum iaculis,
malesuada proin vestibulum suspendisse pellentesque wisi.
Faucibus turpis a ac. Wisi eros sed sit nec sed,
sed et fringilla vulputate mattis pretium,
rutrum vitae vitae euismod erat eu.
Ac feugiat sed elit, pellentesque amet dis,
non lorem vero rutrum, vel eu sodales orci a,
vestibulum ante consectetur.
Dui wisi massa a ut seddictumst,
ultricies sed metus,
orci urna amet mauris nibh, leo nec fusce.
Output of test.txt:
A nulla odio aptent metus,
mattis mattis elementum iaculis,
malesuada proin vestibulum suspendisse pellentesque wisi.
Faucibus turpis a ac. Wisi eros sed sit nec sed,
sed et fringilla vulputate mattis pretium,
rutrum vitae vitae euismod erat eu.
Ac feugiat sed elit, pellentesque amet dis,
non lorem vero rutrum, vel eu sodales orci a,
vestibulum ante consectetur.
Dui wisi massa a ut seddictumst,
ultricies TEMPOR metus,
orci urna amet mauris nibh, leo nec fusce.
Hopefully it answers your question.
Upvotes: 0
Reputation: 591
This is the right way to do it as you tried:
(Get-Content -Path C:\temp\test.txt -Raw) -replace '(.*)abc$', 'HelloWorld' | Out-File C:\temp\test.txt
And this is another way to do it:
$lines = Get-Content -Path C:\temp\test.txt
$last = $lines.Length - 1
$lines[$last] = "testtest"
Set-Content -Path C:\temp\test.txt -Value $lines
Upvotes: -1