sed 用于替换的反向引用



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

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

但它不起作用。 如何重复使用2来替换其内容?

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只要替换成功

gnu sed:

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

这个想法是,用-替换所有_,然后恢复要保留的那些。

更新

如果用_分隔的字段包含-,我们可以利用 GNU sedge

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_----    

按照 Kent 的建议,如果您不需要通用解决方案,这有效:

$ 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 包含"-"字符,则会失败。

最新更新