sed反向引用用于替换

时间:2018-12-04 09:03:52

标签: regex sed backreference

有一个字符串a_b_c_d。我想在_-之间的字符串中用a_替换_d。下面是处理过程。

echo "a_b_c_d" | sed -E 's/(.+)_(.+)_(.+)/\1`s/_/-/g \2`\3/g'

但是它不起作用。如何重用\2替换其内容?

3 个答案:

答案 0 :(得分:1)

Perl允许在带有e修饰符的替换部分中使用代码

$ echo 'a_b_c_d' | perl -pe 's/a_\K.*(?=_d)/$&=~tr|_|-|r/e'
a_b-c_d
$ echo 'x_a_b_c_y' | perl -pe 's/x_\K.*(?=_y)/$&=~tr|_|-|r/e'
x_a-b-c_y
  • $&=~tr|_|-|r,这里$&是匹配的部分,并且在其上应用tr,将_替换为-
  • a_\K这将与a_匹配,但不会成为匹配部分的一部分
  • (?=_d)积极匹配_d,但不会成为匹配部分的一部分


使用sed(已在GNU sed 4.2.2上测试,不确定其他版本的语法)

$ echo 'a_b_c_d' | sed -E ':a s/(a_.*)_(.*_d)/\1-\2/; ta'
a_b-c_d
$ echo 'x_a_b_c_y' | sed -E ':a s/(x_.*)_(.*_y)/\1-\2/; ta'
x_a-b-c_y
  • :a标签a
  • s/(a_.*)_(.*_d)/\1-\2/_-之间用a_替换一个_d
  • 只要替换成功,
  • ta就会贴上标签a

答案 1 :(得分:1)

gnu sed:

$ sed -r 's/_/-/g;s/(^[^-]+)-/\1_/;s/-([^-]+$)/_\1/' <<<'x_a_b_c_y'
x_a-b-c_y

想法是,将所有_替换为-,然后还原您要保留的内容。

更新

如果用_分隔的字段包含-,我们可以使用ge的gnu sed:

 sed -r 's/(^[^_]+_)(.*)(_[^_]+$)/echo "\1"$(echo "\2"\|sed "s|_|-|g")"\3"/ge'

例如,我们希望----_f-o-o_b-a-r_--------_f-o-o-b-a-r_----

 sed -r 's/(^[^_]+_)(.*)(_[^_]+$)/echo "\1"$(echo "\2"\|sed "s|_|-|g")"\3"/ge' <<<'----_f-o-o_b-a-r_----'
----_f-o-o-b-a-r_----    

答案 2 :(得分:0)

按照肯特的建议,如果您不需要一般的解决方案,则可以这样做:

$ echo 'a_b_c+d_x' | tr '_' '-' | sed -E 's/^([a-z]+)-(.+)-([a-z]+)$/\1_\2_\3/g'
$ a_b-c+d_x

应该调整字符类以匹配输入字符串的开头和结尾部分。当然,如果a或x包含'-'字符,则失败。