regexp(sed)抑制“不匹配”输出

时间:2011-05-15 22:23:20

标签: regex bash shell sed

我坚持下去并且无法绕过它:我怎么能告诉sed返回找到的值,否则闭嘴

这真的超越了我:如果他找不到任何东西,为什么sed会返回整个字符串?我是否必须在返回的字符串上运行另一个测试来验证它?我尝试在(非常简短的)手册页中使用“-n”,但它有效地抑制了所有输出,包括匹配的字符串。

这就是我现在所拥有的:

echo plop-02-plop | sed -e 's/^.*\(.\)\([0-9][0-9]\)\1.*$/\2/'

返回 02(这很好,花花公子,非常感谢你),但是:

echo plop-02plop | sed -e 's/^.*\(.\)\([0-9][0-9]\)\1.*$/\2/'

返回 plop-02plop(什么时候应该返回这个=“”没什么!Dang,你什么都没发现所以安静!  大声喊叫!!)

我尝试检查返回值,但这也失败了!加斯普!!

$ echo plop-02-plop | sed -e 's/^.*\(.\)\([0-9][0-9]\)\1.*$/\2/' ; echo $?
02
0
$ echo plop-02plop | sed -e 's/^.*\(.\)\([0-9][0-9]\)\1.*$/\2/' ; echo $?
plop-02plop
0
$

这最后一个我甚至不敢相信。 sed真的是我应该使用的工具吗?我想从大海捞针中取出一根针,我想要一根针或没什么 ..?

2 个答案:

答案 0 :(得分:24)

默认情况下,

sed打印所有行。

你想做的是

/patt/!d;s//repl/

IOW删除与您的模式不匹配的行,如果它们匹配,则从中提取特定元素,例如给出捕获组号。在你的情况下,它将是:

sed -e '/^.*\(.\)\([0-9][0-9]\)\1.*$/!d;s//\2/'

您还可以使用-n选项来禁止回显所有行。然后只有在您明确说明行时才打印行。实际上,使用-n的脚本通常更长,维护起来更麻烦。这将是:

sed -ne 's/^.*\(.\)\([0-9][0-9]\)\1.*$/\2/p'

还有grep,但是你的例子显示,为什么sed有时会更好。

答案 1 :(得分:2)

也许您可以使用egrep -o

input.txt中:

blooody
aaaa
bbbb
odor
qqqq

E.g。

sehe@meerkat:/tmp$ egrep -o o+ input.txt 
ooo
o
o
sehe@meerkat:/tmp$ egrep -no o+ input.txt 
1:ooo
4:o
4:o

当然egrep对于高级构造(反向引用,非贪婪运算符)将具有稍微不同(更好?)的正则表达式语法。如果你喜欢这种方法,我会让你做翻译。