给定这样的文件:
a
b
a
b
Run Code Online (Sandbox Code Playgroud)
我希望能够用来sed替换文件中包含"a"实例的最后一行.因此,如果我想用"c"替换它,那么输出应该如下所示:
a
b
c
b
Run Code Online (Sandbox Code Playgroud)
请注意,无论可能遇到多少匹配,或者确切了解所需模式或文件内容的详细信息,我都需要这样做.提前致谢.
gle*_*man 12
不完全是sed:
tac file | sed '/a/ {s//c/; :loop; n; b loop}' | tac
Run Code Online (Sandbox Code Playgroud)
测试
% printf "%s\n" a b a b a b | tac | sed '/a/ {s//c/; :loop; n; b loop}' | tac
a
b
a
b
c
b
Run Code Online (Sandbox Code Playgroud)
反转文件,然后进行第一次匹配,进行替换,然后无条件地填充文件的其余部分.然后重新反转文件.
注意,空正则表达式(此处为s//c/)表示重用前一个正则表达式(/a/)
除了非常简单的程序,我不是一个巨大的sed粉丝.我会用awk:
tac file | awk '/a/ && !seen {sub(/a/, "c"); seen=1} 1' | tac
Run Code Online (Sandbox Code Playgroud)
这里有很多很好的答案;这是一个概念上简单的两遍sed解决方案,tail它符合 POSIX 标准并且不会将整个文件读入内存,类似于Eran Ben-Natan 的方法:
sed "$(sed -n '/a/ =' file | tail -n 1)"' s/a/c/' file
Run Code Online (Sandbox Code Playgroud)
sed -n '/a/=' file输出数字线(函数=)匹配正则表达式a,以及tail -n 1提取输出的最后一行,即在文件中的行的数量file含有最后的正则表达式的发生。
将命令替换$(sed -n '/a/=' file | tail -n 1)直接' s/a/c'放在导致外部sed脚本(例如3 s/a/c/(带有样本输入))之前,它仅在最后一个出现正则表达式的地方执行所需的替换。
如果在输入文件中找不到模式,则整个命令是有效的空操作。