echo 'bar=start "bar=second CONFIG="$CONFIG bar=s buz=zar bar=g bar=ggg bar=f bar=foo bar=zoo really?=yes bar=z bar=yes bar=y bar=one bar=o que=idn"' | sed -e 's/^\|\([ "]\)bar=[^ ]*[ ]*/\1/g'
实际输出:
CONFIG="$CONFIG buz=zar bar=ggg bar=foo really?=yes bar=yes bar=one que=idn"
预期产出:
CONFIG="$CONFIG buz=zar really?=yes que=idn"
我的正则表达式中缺少什么?
修改:
这可以按预期工作(使用GNU sed
):
's/\(^\|\(['\''" ]\)\)bar=[^ ]*/\2/g; s/[ ][ ]\+/ /g; s/[ ]*\(['\''"]\+\)[ ]*/\1/g'
答案 0 :(得分:2)
sed正则表达式非常有限。例如,它们不包括\ w作为[a-zA-Z0-9_]的同义词。它们也不包括\ b,这意味着在单词的开头或结尾处的零长度字符串(在这种情况下你真的想要......)。
s/ bar=[^ ]* *//
已关闭,但问题是尾随*
会删除可能在下一个bar=
之前的空格。因此,在... bar=aaa bar=bbb ...
中,第一个匹配为bar=aaa
,让bar=bbb ...
尝试进行第二次匹配,但由于您已经占用了bar
之前的空格,因此无法匹配。
s/ bar=[^ ]*//
更好 - 不要消耗尾随空格,留下它们用于下一次匹配尝试。如果你想匹配bar=something
,即使它位于字符串的开头,请先在开头插入一个空格:
sed 's/^bar=/ bar=/; s/ bar=[^ ]*//'
答案 1 :(得分:1)
如果您要删除bar=something
的所有实例,那么您可以简化正则表达式:
\sbar=\w+
这匹配所有bar=
加上所有整个单词。 bar=
前面必须有空白字符。
演示: https://regex101.com/r/xbBhJZ/3
as sed:
s/\sbar=\w\+//g
这正确地说明了foobar = bar。
与Waxrat的答案一样,您必须在开头插入一个空格才能正确匹配,因为它现在与bar=
之前的空白字符匹配。这可以很容易地完成,因为你明确地引用了你的字符串。