sed: Как я могу напечатать все соответствия в каждой строке? - PullRequest
1 голос
/ 12 июня 2019

У меня есть строка из двух строк:

> 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

Он печатает только последнее совпадение каждой строки: -)

Как напечатать все соответствующие группы?

Ответы [ 2 ]

2 голосов
/ 12 июня 2019

Используйте 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

См. онлайн-демонстрацию

1 голос
/ 13 июня 2019

Это может сработать для вас (GNU sed):

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

Окружите необходимые строки новыми строками, а затем напечатайте только эти строки.

Или, если вы предпочитаете:

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