给出以下句子:“我的#1例子!”,在bash中我想用'test'替换'my'(我的包括)之前的所有内容。 我在做:
echo "something my #1 example!" | sed s/.+my/test/g
预期结果应为:
test #1 example!
但实际结果是:
something my #1 example!
我假设它找不到匹配的表达式,即使它在这里工作:http://regexr.com/3beg4
答案 0 :(得分:3)
对于GNU sed(最可能的情况),您需要使用扩展正则表达式(带有-r
或--regexp-extended
标志之一),或者如果您使用+
则转义想继续使用基本的正则表达式。
有关详细信息,请参阅以下文字:
pax> echo "something my #1 example!" | sed 's/.+my/test/g'
something my #1 example!
pax> echo "something my #1 example!" | sed -r 's/.+my/test/g'
test #1 example!
pax> echo "something my #1 example!" | sed 's/.\+my/test/g'
test #1 example!
根据sed
信息页面:
基本和扩展正则表达式之间的唯一区别在于几个字符的行为:
'?'
,'+'
,括号,大括号'{}'
和'|'
。< / p>虽然基本正则表达式要求对它们进行转义(如果您希望它们表现为特殊字符),使用扩展正则表达式时,如果希望它们匹配文字字符,则必须将它们转义的
如果您没有使用具有此级别支持的sed
,则通常可以将'.+'
转换为'..*'
以达到相同的效果。
答案 1 :(得分:0)
你在问题标题中说bash正则表达式,然后写了一些关于sed的内容。以下是如何在纯粹的bash中做到这一点:
foo="something my #1 example!";
while [[ $foo =~ (.+my)(.*) ]]; do # loop instead of if, for /g.
foo="test${BASH_REMATCH[2]}";
# If your pattern can match the replacement, then just loop over BASH_REMATCH[2]
done;
echo "$foo"
Bash没有替换正则表达式运算符,因此您必须通过在要修改的部分之前/之后捕获(.*)
来模拟它。
如果要修改shell变量中的字符串,这可能比sed
更有效。如果您只是将stdin过滤到stdout,那么sed会保存您编写read
循环,并且bash在处理大型文本流时要比sed / grep慢得多。