Печать с помощью sed или awk строки, соответствующей шаблону соответствия
Вопрос: Я хотел бы напечатать одну строку непосредственно после строки, которая содержит соответствующий шаблон.
Моя версия sed
не будет использовать следующий синтаксис (он +1p
на +1p
), который может показаться простым решением:
sed -n '/ABC/,+1p' infile
Я предполагаю, что awk
было бы лучше сделать многострочную обработку, но я не уверен, как это сделать.
Ответы
Ответ 1
Никогда не используйте слово "шаблон", поскольку оно очень неоднозначно. Всегда используйте "string" или "regexp" (или в шаблоне "globbing" оболочки), в зависимости от того, что вы действительно имеете в виду.
Конкретный ответ:
awk 'f{print;f=0} /regexp/{f=1}' file
или специализируя более общее решение N-й записи после регулярного выражения (идиома "c" ниже):
awk 'c&&!--c; /regexp/{c=1}' file
Следующие идиомы описывают, как выбрать диапазон записей, заданных для определенного регулярного выражения:
a) Распечатайте все записи из некоторого регулярного выражения:
awk '/regexp/{f=1}f' file
b) Распечатайте все записи после некоторого регулярного выражения:
awk 'f;/regexp/{f=1}' file
c) Распечатайте N-ю запись после некоторого регулярного выражения:
awk 'c&&!--c;/regexp/{c=N}' file
d) Распечатайте каждую запись, кроме N-й записи, после некоторого регулярного выражения:
awk 'c&&!--c{next}/regexp/{c=N}1' file
e) Распечатайте N записей после некоторого регулярного выражения:
awk 'c&&c--;/regexp/{c=N}' file
f) Распечатайте каждую запись, кроме N записей, после некоторого регулярного выражения:
awk 'c&&c--{next}/regexp/{c=N}1' file
g) Распечатайте N записей из некоторого регулярного выражения:
awk '/regexp/{c=N}c&&c--' file
Я изменил имя переменной из "f" для "found" на "c" для "count", где
подходящий, поскольку это более выразительно, что переменная на самом деле есть.
Ответ 2
Это линия после этого матча, в которой вы интересны, не так ли? В sed это может быть выполнено следующим образом:
sed -n '/ABC/{n;p}' infile
В качестве альтернативы вариант grep A может быть тем, что вы ищете.
-A NUM, Print NUM lines of trailing context after matching lines.
Например, учитывая следующий входной файл:
foo
bar
baz
bash
bongo
Вы можете использовать следующее:
$ grep -A 1 "bar" file
bar
baz
$ sed -n '/bar/{n;p}' file
baz
Надеюсь, что это поможет.
Ответ 3
Мне нужно было напечатать ВСЕ строки после шаблона (ok Ed, REGEX), поэтому я остановился на этом:
sed -n '/pattern/,$p' # prints all lines after ( and including ) the pattern
Но так как я хотел напечатать все строки AFTER (и исключить шаблон)
sed -n '/pattern/,$p' | tail -n+2 # all lines after first occurrence of pattern
Я полагаю, что в вашем случае вы можете добавить head -1
в конец
sed -n '/pattern/,$p' | tail -n+2 | head -1 # prints line after pattern
Ответ 4
awk Версия:
awk '/regexp/ { getline; print $0; }' filetosearch
Ответ 5
Если совпадение с образцом, скопируйте следующую строку в буфер шаблона, удалите возвращаемый результат, а затем - выход из строя.
sed '/pattern/ { N; s/.*\n//; q }; d'
Ответ 6
На самом деле sed -n '/pattern/{n;p}' filename
выйдет из строя, если строки pattern
соответствуют continuous
:
$ seq 15 |sed -n '/1/{n;p}'
2
11
13
15
Ожидаемые ответы должны быть:
2
11
12
13
14
15
Мое решение:
$ sed -n -r 'x;/_/{x;p;x};x;/pattern/!s/.*//;/pattern/s/.*/_/;h' filename
Например:
$ seq 15 |sed -n -r 'x;/_/{x;p;x};x;/1/!s/.*//;/1/s/.*/_/;h'
2
11
12
13
14
15
Объясняет:
-
x;
: в начале каждой строки из ввода используйте команду x
для обмена содержимым в pattern space
и hold space
.
-
/_/{x;p;x};
: if pattern space
, который является hold space
на самом деле, содержит _
(это всего лишь indicator
, указывающий, соответствует ли последняя строка pattern
или нет), затем используйте x
для обмена фактическим содержимым current line
до pattern space
используйте p
для печати current line
и x
, чтобы восстановить эту операцию.
-
x
: восстановить содержимое в pattern space
и hold space
.
-
/pattern/!s/.*//
: if current line
НЕ соответствует pattern
, что означает, что мы НЕ должны печатать следующую строку NEXT, а затем использовать команду s/.*//
для удаления всего содержимого в pattern space
.
-
/pattern/s/.*/_/
: if current line
соответствует pattern
, что означает, что мы должны напечатать следующую строку ниже, тогда нам нужно установить indicator
, чтобы сообщить sed
распечатать NEXT строку, поэтому используйте s/.*/_/
для замены всего содержимого pattern space
на _
(вторая команда будет использовать его, чтобы судить, соответствует ли последняя строка pattern
или нет).
-
h
: перезапишите hold space
содержимое в pattern space
; то содержимое в hold space
равно ^_$
, что означает, что current line
соответствует pattern
или ^$
, что означает, что current line
НЕ соответствует pattern
.
- пятый шаг и шестой шаг не могут быть обменены, потому что после
s/.*/_/
pattern space
НЕ может соответствовать /pattern/
, поэтому s/.*//
ДОЛЖЕН быть выполнен!
Ответ 7
Это может сработать для вас (GNU sed):
sed -n ':a;/regexp/{n;h;p;x;ba}' file
Используйте seds grep-like option -n
, и если текущая строка содержит требуемое regexp, замените текущую строку следующим, скопируйте эту строку в пространство удержания (HS), распечатайте строку, поменяйте пространство рисунка (PS ) для HS и повторите.