cat test1
a a 1 a aa 1 1 111 bb b
a1b a 11 b b b
1 asd fdg 1 bb b
我想用@替换每行显示的末尾"1",使其他数据保持不变。我的预期结果
cat expected_result
a a 1 a aa 1 1 11@ bb b
a1b a 1@ b b b
1 asd fdg @ bb b
这种情况可以通过"sed"解决吗?我不知道如何选择每行中的最后一个"1",谢谢。
方法 1:
1([^1]*)$
匹配行上的最后一个1
以及之后的所有内容:
$ sed -E 's/1([^1]*)$/@1/' test1
a a 1 a aa 1 1 11@ bb b
a1b a 1@ b b b
1 asd fdg @ bb b
方法2:
(.*)1
匹配行上的所有内容,包括最后1
:
$ sed -E 's/(.*)1/1@/' test1
a a 1 a aa 1 1 11@ bb b
a1b a 1@ b b b
1 asd fdg @ bb b
这是有效的,因为 sed 的正则表达式是贪婪的(更准确地说,最左边最长(。 (.*)1
最左边最长的匹配将从行的开头到行上的最后一个1
匹配。
试试这个。 *
贪婪,试图尽可能多地匹配,1/1@/
将匹配每行1
的最后一次出现并替换为@
。如果有其他类似"x"的东西来匹配并用y
替换最后一个出现,那么它应该是x/1y/
sed 's/(.*)1/1@/' filename
输出:
a a 1 a aa 1 1 11@ bb b
a1b a 1@ b b b
1 asd fdg @ bb b
也使用rev
和awk
解决方案。
rev Input_file | awk '{sub(/1/,"@");print}' | rev
输出将如下所示。
a a 1 a aa 1 1 11@ bb b
a1b a 1@ b b b
1 asd fdg @ bb b
1([^1]*$(,将匹配最新的 1 和任何前面的内容。
sed -r 's/1([^1]*$)/@1/' v1
cat test@
a a 1 a aa 1 1 11@ bb b
a1b a 1@ b b b
1 asd fdg @ bb b
猫 v1
cat test1
a a 1 a aa 1 1 111 bb b
a1b a 11 b b b
1 asd fdg 1 bb b