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

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

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

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

pass2: <Marvell Console 1.01> Removable Processor SCSI device

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

dmesg | <sed command>

应该输出:

Marvell Console 1.01

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

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

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

答案1

尝试这个,

sed -nE 's/^pass2:.*<(.*)>.*$/\1/p'

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

sed -n 's/^pass2:.*<\(.*\)>.*$/\1/p'

输出:

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

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

答案2

-o在 grep 下只打印匹配的部分怎么样?不过,我们仍然需要删除<>, buttr在那里工作。

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

答案3

我使用 sed、awk 和 python 尝试了以下 3 种方法

sed命令

echo "pass2: <Marvell Console 1.01> Removable Processor SCSI device" | sed "s/.*<//g"|sed "s/>.*//g"

输出

Marvell Console 1.01

awk 命令

echo "pass2: <Marvell Console 1.01> Removable Processor SCSI device" | awk -F "[<>]" '{print $2}'

输出

Marvell Console 1.01

Python

#!/usr/bin/python
import re
h=[]
k=open('l.txt','r')
l=k.readlines()
for i in l:
    o=i.split(' ')
    for i in o[1:4]:
        h.append(i)
print (" ".join(h)).replace('>','').replace('<','')

输出

Marvell Console 1.01

答案4

您可以使用以下grep -o -e命令提取子字符串:

cat some.log | grep "lineWithThisText" | grep -o -e 'SomeSequence1[0-9]*[A-Z]*SomeSequence2'

由于某种原因,此 grep regex match 命令中的 1 个或多个匹配项*不起作用。+

使用以下命令阅读 grep 手册:

man grep

阅读有关选项-o和 的信息-e

我在工作中使用它从多个日志行中提取大量数据。

相关内容