如何用sed替换文件中最后一个January为July?及失效原因解析
用sed替换文件中最后出现的"January"为"July"的问题
需求说明
我有一个文本文件内容如下:
--abcdef12 -- February April January January March January January January January --abcdef12 --
需要将文件中**最后出现的"January"**替换为"July",期望输出:
--abcdef12 -- February April January January March January January January July --abcdef12 --
尝试过的方法及失效原因
方法1:仅定位最后一行替换
执行命令:
sed '$ s/January/July/' test.txt
输出结果:
--abcdef12 -- February April January January March January January January January --abcdef12 --
失效原因:
命令里的$是指定处理文件的最后一行,但原文件最后一行是--abcdef12 --,根本没有"January",所以完全没触发替换操作。
方法2:每行替换最后一个匹配项
执行命令:
sed 's/\(.*\)January/\1July/' test.txt
输出结果:
--abcdef12 -- February April July January March July January January July --abcdef12 --
失效原因:
这个正则表达式里的\(.*\)是贪婪匹配,会抓取每行中最后一个"January"之前的所有内容,然后把该行的最后一个"January"替换成"July"。它的作用范围是每一行,而不是整个文件,所以会把所有行的最后一个"January"都换掉,不符合只替换整个文件最后一个的需求。
正确的sed解决方案
要实现仅替换整个文件中最后一个"January",可以借助文件反转的思路:
tac test.txt | sed '0,/January/s//July/' | tac
操作逻辑:
tac命令把文件内容行反转,原文件最后一行变第一行,包含最后一个"January"的行变成第二行sed '0,/January/s//July/'仅替换反转后文件中第一个出现的January,也就是原文件里最后出现的那个- 再用
tac把内容反转回来,就得到了期望的输出
内容的提问来源于stack exchange,提问作者Resmi R
相关产品推荐
相关产品推荐

