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

发布于 2024-11-07 09:30:02 字数 840 浏览 0 评论 0原文

我被困在这个问题上,无法理解它:我怎样才能告诉 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 (当它应该返回 this = "" 什么都没有!天啊,你什么也没发现,所以安静点! 大声喊叫!!)

我尝试检查返回值,但这也失败了!喘气!!

$ 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 真的是我应该使用的工具吗?我想大海捞针,我想要一根针,还是什么都没有..?

I'm stuck on that and can't wrap my head around it: How can I tell sed to return the value found, and otherwise shut up?

It's really beyond me: Why would sed return the whole string if he found nothing? Do I have to run another test on the returned string to verify it? I tried using "-n" from the (very short) man page but it effectively suppresses all output, including matched strings.

This is what I have now :

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

which returns
02 (and that is fine and dandy, thank you very much), but:

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

returns
plop-02plop (when it should return this = "" nothing! Dang, you found nothing so be quiet!
For crying out loud !!)

I tried checking for a return value, but this failed too ! Gasp !!

$ 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
$

This last one I cannot even believe. Is sed really the tool I should be using? I want to extract a needle from a haystack, and I want a needle or nothing..?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

简单 2024-11-14 09:30:02

sed 默认情况下打印所有行。

您想要做的是:

/patt/!d;s//repl/

换句话说,删除与您的模式不匹配的行,对于匹配的行,从中提取特定元素,例如给出捕获组编号。在您的情况下,它将是:

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

您还可以使用 -n 选项来抑制回显所有行。然后,仅当您明确声明该行时,才会打印该行。实际上,使用 -n 的脚本通常更长且维护起来更麻烦。这里是:

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

还有 grep,但您的示例显示了为什么 sed 有时更好。

sed by default prints all lines.

What you want to do is:

/patt/!d;s//repl/

In other words, delete lines not matching your pattern, and for lines that do match, extract particular element from it, giving capturing group number for instance. In your case it will be:

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

You can also use -n option to suppress echoing all lines. Then line is printed only when you explicitly state it. In practice, scripts using -n are usually longer and more cumbersome to maintain. Here it will be:

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

There is also grep, but your example shows why sed is sometimes better.

深陷 2024-11-14 09:30:02

也许你可以使用egrep -o

input.txt:

blooody
aaaa
bbbb
odor
qqqq

例如,

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 的高级构造(反向引用、非贪婪运算符)的正则表达式语法略有不同(更好?)。如果你喜欢这种方法,我会让你做翻译。

Perhaps you can use 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

Of course egrep will have slightly different (better?) regex syntax for advanced constructs (back-references, non-greedy operators). I'll let you do the translation, if you like the approach.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文