如何替换每行中持续的特殊字符

时间:2018-01-12 05:42:35

标签: shell awk sed

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"在每一行,谢谢。

4 个答案:

答案 0 :(得分:5)

方法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 :(得分:3)

你可以试试这个。 *贪婪,尝试尽可能匹配,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

答案 2 :(得分:2)

此处也使用revawk解决方案。

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

答案 3 :(得分:1)

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

cat 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