我的 a.txt 包含以下内容:
apple
123
pear
1234
如果我运行下面的命令,
sed 's/123/AAA/p' a.txt
我以为我会得到
apple
123
AAA
pear
1234
AAA4
因为 sed 默认会自动打印每一行。我原本期望修改后的输出是在模式空间中被修改之后。但我的实际输出打印了两次替换:
apple
AAA
AAA
pear
AAA4
AAA4
这是为什么?
答案1
sed 's/123/AAA/p' a.txt
此表达式包含两个命令
s/123/AAA/
意思是,找到带有 的行,123
并在出现 的行中将其替换123
为AAA
。默认情况下,sed
打印每一行,因此,整个流都会打印修改内容p
意思是打印模式空间。在我们调用 的地方p
,模式空间包含修改后的行,因此再次打印它们。
当我们只想打印由 发现并因此发生改变的流的行时,s
和的组合p
通常与 一起使用。-n
s
命令的顺序很重要。在您的命令中,如果您p
先输入,它将打印未修改的流,接近您的预期:
$ sed 'p;s/123/AAA/' a.txt
apple
apple
123
AAA
pear
pear
1234
AAA4
这里当我们调用时p
,模式空间是整个文件,因为我们没有指定它的任何部分,并且它没有被更改。该s
命令还会打印整个文件,但也会对其进行修改,因此我们会看到两次流,一次是修改的,一次是未修改的。1
因此,也许认为表达式中的命令sed
是从左到右累积应用的会有所帮助,并且正如steeldriver所说,在这种情况下得到的输出是由于p
在循环结束时应用的,之后s
已用于选择和修改文件的一部分。
1最初,我在这里使用的命令是sed 'ps/123/AAA/' a.txt
。正如mxmlnkn 的评论,此命令在 GNU 中不起作用sed
。我一直在使用 BusyBox sed
(在 Android 上的 Termux 中),并且没有在sed
Ubuntu 上的 GNU 中正确测试该命令(糟糕!)。但有趣的是,GNUsed
与其他命令不同,在这里需要分号。