sed: фильтровать подмножество строк из строк, соответствующих регулярному выражению - PullRequest
0 голосов
/ 02 апреля 2020

У меня есть файл следующего формата:

abc: A B C D E
abc: 1 2 3 4 5 
def  D E F G H
def: 10 11 12 23 99
...

Это первая строка со строками, после ':' - заголовок для следующей строки с числами. Я хотел бы использовать sed для извлечения только строки, начинающейся со строки PATTERN с числами в строке.

Число чисел в строке является переменным, но предположим, что я точно знаю, сколько я Я ожидаю, поэтому я попробовал эту команду:

% sed 's/^abc: \([0-9]+ [0-9]+ [0-9]+\)$/\1/g' < file.txt

Но он выводит все записи из файла. Что я делаю не так?

Ответы [ 4 ]

1 голос
/ 02 апреля 2020
  1. sed выполняет подстановки и печатает каждую строку независимо от того, происходит ли подстановка.

  2. Ваше регулярное выражение неверно. Он будет соответствовать только трем числам, разделенным пробелами, если задан расширенный флаг регулярного выражения (-E). Без этого даже не это, потому что знак + будет интерпретироваться буквально.

  3. Лучше всего здесь использовать адреса и только те строки, которые имеют совпадение:

sed -nE '/^abc: [0-9]+ [0-9]+ [0-9]+ [0-9]+ [0-9]+$/p' < file.txt

или лучше,

sed -nE '/^abc:( [0-9]+){5}$/p' < file.txt

Флаг -n отключает поведение «print all lines» sed, описанное в (1). Будут напечатаны только строки, которые достигают команды p.

1 голос
/ 02 апреля 2020

С дополнительным вопросом @ Mark в комментарии "Если я хочу просто извлечь совпадающие числа (и удалить префикс, например, ab c)…" , это шаблон, который я придумал:

sed -En 's/^abc: (([0-9]+[ \t]?)+)[ \t]*$/\1/gp' file.txt

Я использую флаг -E для расширенных регулярных выражений, чтобы избежать всего необходимого экранирования.
Учитывая этот файл:

abc: A B C D E
abc: 1 2 3 4 5 
abc: 1 c9 A 7f
def  D E F G H
def: 10 11 12 23 99

… this регулярное выражение соответствует abc: 1 2 3 4 5, исключая abc: 1 c9 A 7f - оно также допускает переменные пробелы и конечные пробелы.

1 голос
/ 02 апреля 2020

для извлечения только строки, начинающейся со строки PATTERN с номерами в строке и Число чисел в строке является переменной означает хотя бы одно число, поэтому:

$ sed -n '/abc: \([0-9]\+\)/p' file

Выход:

abc: 1 2 3 4 5 

Точно с 5 числами используйте:

$ sed -n '/abc: \([0-9]\+\( \|$\)\)\{5\}/p' file
0 голосов
/ 03 апреля 2020

С любым седом:

$ sed -n 's/^abc: \([0-9 ]*\)$/\1/p' file
1 2 3 4 5
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...