有一个字符串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 包含"-"字符,则会失败。