sed:如何打印每行中的所有匹配项?

sed:如何打印每行中的所有匹配项?,sed,Sed,我有一个两行字符串: > a="Microarchitectural Data Sampling (MDS) aka CVE-2018-12126, CVE-2018-12127,CVE-2018-12130, CVE-2019-11091, publicly announced by Intel on 5/14/2019, this has high visibility and lots of public media exposure.\nMicroarchitectural Dat

我有一个两行字符串:

> a="Microarchitectural Data Sampling (MDS) aka CVE-2018-12126, CVE-2018-12127,CVE-2018-12130, CVE-2019-11091, publicly announced by Intel on 5/14/2019, this has high visibility and lots of public media exposure.\nMicroarchitectural Data Sampling (MDS) aka CVE-2018-12126, CVE-2018-12127,CVE-2018-12130, CVE-2019-11091, publicly announced by Intel on 5/14/2019, this has high visibility and lots of public media exposure."
> echo -e $a
Microarchitectural Data Sampling (MDS) aka CVE-2018-12126, CVE-2018-12127,CVE-2018-12130, CVE-2019-11091, publicly announced by Intel on 5/14/2019, this has high visibility and lots of public media exposure.
Microarchitectural Data Sampling (MDS) aka CVE-2018-12126, CVE-2018-12127,CVE-2018-12130, CVE-2019-11091, publicly announced by Intel on 5/14/2019, this has high visibility and lots of public media exposure.
我想打印的是:

CVE-2018-12126 CVE-2018-12127 CVE-2018-12130 CVE-2019-11091
CVE-2018-12126 CVE-2018-12127 CVE-2018-12130 CVE-2019-11091
# OR
CVE-2018-12126
CVE-2018-12127
CVE-2018-12130
CVE-2019-11091
CVE-2018-12126
CVE-2018-12127
CVE-2018-12130
CVE-2019-11091
我试过以下方法:

> echo -e $a | sed -r 's/.*(CVE-[0-9]{4}-[0-9]{4,6}).*/\1/g'
CVE-2019-11091
CVE-2019-11091
它只打印每行的最后一个匹配项:-)


如何打印所有匹配的组?

使用
grep
-o
选项,仅输出匹配的子字符串:

grep -o 'CVE-[0-9]\{4\}-[0-9]\{4,6\}' file > outputfile
注意,
\{4\}
中的大括号是转义的,因为这是默认的POSIX BRE引擎兼容正则表达式

对于,简单的解决方案是使用两个步骤:用换行符包装预期的匹配项,然后提取与您的模式完全匹配的匹配项:

pat='CVE-[0-9]\{4\}-[0-9]\{4,6\}'
sed "s/$pat/\n&\n/g"  file.txt | sed -n "/^$pat\$/p" > outputfile
输出:

CVE-2018-12126
CVE-2018-12127
CVE-2018-12130
CVE-2019-11091
CVE-2018-12126
CVE-2018-12127
CVE-2018-12130
CVE-2019-11091

请参见将
grep
-o
一起使用选项,该选项将仅输出匹配的子字符串:

grep -o 'CVE-[0-9]\{4\}-[0-9]\{4,6\}' file > outputfile
注意,
\{4\}
中的大括号是转义的,因为这是默认的POSIX BRE引擎兼容正则表达式

对于,简单的解决方案是使用两个步骤:用换行符包装预期的匹配项,然后提取与您的模式完全匹配的匹配项:

pat='CVE-[0-9]\{4\}-[0-9]\{4,6\}'
sed "s/$pat/\n&\n/g"  file.txt | sed -n "/^$pat\$/p" > outputfile
输出:

CVE-2018-12126
CVE-2018-12127
CVE-2018-12130
CVE-2019-11091
CVE-2018-12126
CVE-2018-12127
CVE-2018-12130
CVE-2019-11091
请参见

这可能适合您(GNU-sed):

用换行符环绕所需字符串,然后仅打印这些行

或者,如果您愿意:

regexp='CVE-[0-9]\{4\}-[0-9]\{4,6\}'
sed '/\n/!s/'$regexp'/\n&\n/g;/^'$regexp'/P;D' file
这可能适用于您(GNU-sed):

用换行符环绕所需字符串,然后仅打印这些行

或者,如果您愿意:

regexp='CVE-[0-9]\{4\}-[0-9]\{4,6\}'
sed '/\n/!s/'$regexp'/\n&\n/g;/^'$regexp'/P;D' file

-o
标志一起使用,如
grep-oE'CVE-[0-9]{4}-[0-9]{4,6}'
。谢谢,
grep-oE
可以工作。顺便说一句,使用sed实现它是可能的吗?是的,但是它不如grep那么健壮。使用
-o
标志,比如
grep-oE'CVE-[0-9]{4}-[0-9]{4,6}'
。谢谢
grep-oE
可以工作。顺便说一句,使用sed实现它有可能吗?是的,但是它没有grep那么健壮。谢谢!一条评论,为什么不使用
grep-E
sed-r
?1.grep
-E,--extended regexp
,将模式解释为扩展正则表达式2。sed
-r,--regexp extended
,在脚本中使用扩展正则表达式。@piglot从我读到的,
-r
是一个较旧的选项,
-E
是较新的选项,在Linux和Mac OS上都能工作。谢谢!一条评论,为什么不使用
grep-E
sed-r
?1.grep
-E,--extended regexp
,将模式解释为扩展正则表达式2。sed
-r,--regexp extended
,在脚本中使用扩展正则表达式。@piglot据我所知,
-r
是一个较旧的选项,
-E
是较新的选项,可以在Linux和Mac OS上运行。