有一个字符串a_b_c_d
。我想在_
和-
之间的字符串中用a_
替换_d
。下面是处理过程。
echo "a_b_c_d" | sed -E 's/(.+)_(.+)_(.+)/\1`s/_/-/g \2`\3/g'
但是它不起作用。如何重用\2
替换其内容?
答案 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包含'-'字符,则失败。