Powershell:替换文件中一行的最后一次出现

时间:2016-03-20 20:11:59

标签: regex powershell pattern-matching

假设我们有一个文件foo.txt:

abc
abc
abc

我想把它变成:

abc
abc
HelloWorld

此命令应该有效:

(gc foo.txt -Raw) -replace '(.*)abc', '$1HelloWorld' | Out-File foo.txt

因为我使用-Raw开关,它一次读取整个文件而不是一行。然后,贪婪的模式(。*)应该匹配到最后一个" abc"并将其替换为" HelloWorld"。

但它不起作用。所有3次出现的" abc"被" HelloWorld"取代,好像" -replace"尽管有-Raw开关,但是一次处理一行文件。

为什么?

3 个答案:

答案 0 :(得分:2)

您必须包含单行模式修饰符(?s),如下所示:

(gc foo.txt -Raw) -replace '(?s)(.*)abc', '$1HelloWorld' | Out-File foo.txt

没有它,.将不会匹配回车符和换行符。

答案 1 :(得分:0)

为了简单起见,我将PS分成多行。我用sed

替换TEMPOR

尝试:

$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
  

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.
  

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.

希望它能回答你的问题。

答案 2 :(得分:-1)

这是您尝试的正确方法:

(Get-Content -Path C:\temp\test.txt -Raw) -replace '(.*)abc$', 'HelloWorld' | Out-File C:\temp\test.txt

这是另一种方法:

$lines = Get-Content -Path C:\temp\test.txt
$last = $lines.Length - 1
$lines[$last] = "testtest"
Set-Content -Path C:\temp\test.txt -Value $lines