Ниже приведен текст в файле:
Pseudo name=Apple
Code=42B
state=fault
Pseudo name=Prance
Code=43B
state=good
Мне нужно grep для "42B" и получить вывод из приведенного выше текста, как:
Pseudo name=Apple
Code=42B
state=fault
Кто - нибудь есть идеи о том , как добиться этого с помощью grep
/ awk
/ sed
?
Ответы:
С
awk
RS=
изменяет разделитель входной записи с новой строки на пустые строки. Если какое-либо поле в записи содержит/42B/
распечатку записи.''
(пустая строка) - это магическое значение, используемое для представления пустых строк в соответствии с POSIX :Выходные абзацы не будут разделены, так как выходной разделитель остается одной новой строкой. Чтобы обеспечить наличие пустой строки между выходными абзацами, установите разделитель выходной записи на две строки:
источник
FILENAME
), неплохо использовать перенаправление, так как это позволяет избежать проблем с именами файлов, содержащими=
или начинающимися с-
(или существующими-
), создает согласованные сообщения об ошибках и избегает выполненияawk
или выполнения другие перенаправления, если входной файл не может быть открыт.Предполагая, что данные структурированы таким образом, что вы всегда хотите использовать строку до и после этого, вы можете использовать переключатели grep
-A
(after) и-B
(before), чтобы указывать, что они включают 1 строку перед совпадением и 1 строку после него:Если вам нужны одинаковые номера строк до и после поискового запроса, вы можете использовать
-C
переключатель (context):Если вы хотите быть более строгим при сопоставлении нескольких строк, вы можете использовать инструмент
pcregrep
, чтобы сопоставить шаблон с несколькими строками:Приведенный выше шаблон соответствует следующему:
-M
- несколько строк'Pseudo.*\n.*42B.*\nstate.*'
- соответствует группе строк, где первая строка начинается со слова,"Pseudo"
за которым следуют любые символы до конца строки\n
, за которыми следуют любые символы до строки,"42B"
за которыми следуют любые символы до другого конца строки (\n
), за которым следует строка"state"
следуют любые символы.источник
-C
(контекст) можно использовать как ярлык, если-A
и-B
совпадают.Вероятно, есть такой же простой способ сделать это с помощью awk, но в perl:
В основном это говорит о том, что файл нужно разбить на куски, разделенные пустыми строками, а затем распечатать только те куски, которые соответствуют вашему регулярному выражению.
источник
cat
;perl -00 -ne 'print if /42B/' file
grep
Некоторые разновидности Unix имеет-p
флаг для «пункта». Я знаю, что AIX делает .будет делать именно то, что вы просите там. У grep у YMMV и GNU нет этого флага.
источник
Другое решение Perl, без завершающей пустой строки:
пример
источник
perl -00 -ne 'print if /42B/' file
.