使用 sed 或 grep 根据正则表达式提取子字符串

Ste*_*ner 5 grep sed regular-expression

在 (BSD) UNIX 环境中,我想使用正则表达式捕获特定的子字符串。

假设dmesg命令输出将包括以下行:

pass2: <Marvell Console 1.01> Removable Processor SCSI device
Run Code Online (Sandbox Code Playgroud)

我想捕获<>字符之间的文本,例如

dmesg | <sed command>

应该输出:

Marvell Console 1.01
Run Code Online (Sandbox Code Playgroud)

但是,如果正则表达式不匹配,则不应输出任何内容。许多解决方案包括sed -e 's/$regex/\1/如果找不到匹配项,将输出整个输入,这不是我想要的。

相应的正则表达式可能是: regex="^pass2\: \<(.*)\>"

我将如何正确地使用sedor进行正则表达式匹配grep?请注意,该grep -P选项在我的 BSD UNIX 发行版中不可用。sed -E但是,该选项可用。

pLu*_*umo 8

尝试这个,

sed -nE 's/^pass2:.*<(.*)>.*$/\1/p'
Run Code Online (Sandbox Code Playgroud)

或 POSIXly(-E截至 2019 年尚未达到 POSIX 标准):

sed -n 's/^pass2:.*<\(.*\)>.*$/\1/p'
Run Code Online (Sandbox Code Playgroud)

输出:

$ printf '%s\n' 'pass2: <Marvell Console 1.01> Removable Processor SCSI device' | sed -nE 's/^pass2:.*<(.*)>.*$/\1/p'
Marvell Console 1.01
Run Code Online (Sandbox Code Playgroud)

这将只打印<...>每一行的最后一次出现。


小智 5

如何-o在grep命令只打印匹配的部分?我们仍然需要删除<>,但tr在那里工作。

dmesg |egrep -o "<([a-zA-Z\.0-9 ]+)>" |tr -d "<>"
Marvell Console 1.01
Run Code Online (Sandbox Code Playgroud)