Единственным путем я могу думать, чтобы сделать, это должно было бы использовать history -d
в $PROMPT_COMMAND
. Проблема с этим или любым подходом состоит в том, что невозможно сказать если команда, из которой выходят с ошибкой или завершенная успешно с ненулевым кодом выхода.
$ grep non_existent_string from_file_that_exists
$ echo $?
1
С awk
awk -v RS='' '/42B/' file
RS=
изменяет входной разделитель записей от новой строки до пустых строк. Если какое-либо поле в записи содержит /42B/
распечатайте запись.
''
(пустая строка), волшебное значение, используемое для представления пустых строк согласно POSIX:
Если RS является пустым, то записи разделяются последовательностями, состоящими из a
<newline>
плюс одна или несколько пустых строк строки начального или конечного пробела не должны приводить к пустым записям вначале или концу входа и a<newline>
всегда будет разделитель полей, каково значение FS.
Выходные абзацы не будут разделены, так как выходной разделитель остается единственной новой строкой. Чтобы гарантировать, что существует пустая строка между выходными абзацами, устанавливает выходной разделитель записей на две новых строки:
awk -v RS='' -v ORS='\n\n' '/42B/' file
Принятие данных структурировано так, чтобы это была всегда строка прежде, и после этого Вы хотите Вас, может использовать grep's -A
(после) и -B
(перед) переключателями, чтобы сказать этому включать 1 строку перед соответствием и 1 строкой после него:
$ grep -A 1 -B 1 "42B" sample.txt
Pseudo name=Apple
Code=42B
state=fault
Если Вы хотите те же числовые оси прежде и после критерия поиска, можно использовать -C
(контекст) переключатель:
$ grep -C 1 "42B" sample.txt
Pseudo name=Apple
Code=42B
state=fault
Если требуется быть более строгими при соответствии нескольким строкам, можно использовать инструмент pcregrep
, соответствовать шаблону по нескольким строкам:
$ pcregrep -M 'Pseudo.*\n.*42B.*\nstate.*' sample.txt
Pseudo name=Apple
Code=42B
state=fault
Вышеупомянутый шаблон соответствует следующим образом:
-M
- несколько строк'Pseudo.*\n.*42B.*\nstate.*'
- соответствует группе строк, где первая строка запускается со слова "Pseudo"
сопровождаемый любыми символами вплоть до конца строки \n
, сопровождаемый любыми символами вплоть до строки "42B"
сопровождаемый любыми символами вплоть до другого конца строки (\n
), сопровождаемый строкой "state"
сопровождаемый любыми символами.-C
(контекст) может использоваться в качестве ярлыка, если -A
и -B
то же.
– David Baggerman
14.07.2013, 03:37
Существует, вероятно, столь же простой способ сделать это с awk, но в жемчуге:
cat file | perl -ne 'BEGIN { $/="\n\n" }; print if $_ =~ /42B/;'
Это в основном говорит, чтобы разделить файл на блоки, разграниченные пустыми строками, затем только распечатать те блоки, которые соответствуют Вашему регулярному выражению.
cat
; perl -00 -ne 'print if /42B/' file
– tripleee
14.07.2013, 10:02
Другое решение perl, без завершающей пустой строки:
perl -00ne 'if ($_ =~ /42B/) {chomp($_); printf "%s\n",$_}' foo
Пример
% perl -00ne 'if ($_ =~ /42B/) {chomp($_); printf "%s\n",$_}' foo
Pseudo name=Apple
Code=42B
state=fault
% cat foo
Pseudo name=Apple
Code=42B
state=fault
Pseudo name=Prance
Code=43B
state=good
grep
некоторых разновидностей Unix имеет флаг -p
для «абзаца». Я знаю, что AIX делает .
grep -p 42B <myfile>
сделает именно то, о чем вы там просите. YMMV и GNU grep не имеют этого флага.
FILENAME
), это не плохая идея использовать перенаправление, поскольку это избегает проблем для имени файла, содержащего=
или запуск с-
(или быть-
), делает для последовательных сообщений об ошибках и старается не работатьawk
или выполнение других перенаправлений, если входной файл не может быть открыт. – Stéphane Chazelas 17.11.2015, 12:22