用 sed 替换文件中最后出现的文本

Replace last text ocurrence in a file with sed

我想替换文件中最后一次出现的单词。

hello
bye
bye
bye
hello

我可以通过指示行号来替换它。

sed -i '4 s/bye/adieu' file

此外,如果出现在最后一行。

sed -i '$ s/hello/salut' file

但是,如何在不指明行号的情况下找到并替换最后一个 bye

一个可能的解决方案使用tac | gnu-sed | sed

tac file | sed '0,/^bye$/ s//adieu/' | tac

hello
bye
bye
adieu
hello

详情:

  • tac 反向打印文件
  • 0,/^bye$/ 匹配从开始到第一次出现 bye line
  • 的一行
  • s//adieu/adieu
  • 替换该行
  • tac 再次反向打印文件以获得原始顺序

或者这个awk解决方案适用于任何版本的awk:

awk 'FNR == NR {if ([=11=] == "bye") last = FNR; next}
FNR == last {[=11=] = "adieu"} 1' file file

hello
bye
bye
adieu
hello

这有点恶心,可能不推荐用于大文件,但它应该有效:

sed -zE '$ s/(.*)bye/adieu/' file

其中-z让sed把整​​个文件看成单行\n穿插,而-E就是用()代替\(\) .

如果一行有可能包含 bye 但不只是 bye,如 goodbye/good bye/等等,那么你可以使用

sed -zE '$ s/(.*)(^|\n)bye($|\n)/adieu/' file