Подтвердить что ты не робот

Печать с помощью sed или awk строки, соответствующей шаблону соответствия

Вопрос: Я хотел бы напечатать одну строку непосредственно после строки, которая содержит соответствующий шаблон.

Моя версия sed не будет использовать следующий синтаксис (он +1p на +1p), который может показаться простым решением:

sed -n '/ABC/,+1p' infile

Я предполагаю, что awk было бы лучше сделать многострочную обработку, но я не уверен, как это сделать.

4b9b3361

Ответ 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 и повторите.