使用sed替换空格分隔的字符串

时间:2016-12-17 23:25:07

标签: regex bash sed

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'

2 个答案:

答案 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=之前的空白字符匹配。这可以很容易地完成,因为你明确地引用了你的字符串。