Как к grep для текста в файле и дисплее абзац, который имеет текст?

Единственным путем я могу думать, чтобы сделать, это должно было бы использовать history -d в $PROMPT_COMMAND. Проблема с этим или любым подходом состоит в том, что невозможно сказать если команда, из которой выходят с ошибкой или завершенная успешно с ненулевым кодом выхода.

$ grep non_existent_string from_file_that_exists
$ echo $?
1
25
01.05.2016, 02:08
5 ответов

С awk

awk -v RS='' '/42B/' file

RS= изменяет входной разделитель записей от новой строки до пустых строк. Если какое-либо поле в записи содержит /42B/ распечатайте запись.

'' (пустая строка), волшебное значение, используемое для представления пустых строк согласно POSIX:

Если RS является пустым, то записи разделяются последовательностями, состоящими из a <newline> плюс одна или несколько пустых строк строки начального или конечного пробела не должны приводить к пустым записям вначале или концу входа и a <newline> всегда будет разделитель полей, каково значение FS.

Выходные абзацы не будут разделены, так как выходной разделитель остается единственной новой строкой. Чтобы гарантировать, что существует пустая строка между выходными абзацами, устанавливает выходной разделитель записей на две новых строки:

awk -v RS='' -v ORS='\n\n' '/42B/' file
39
27.01.2020, 19:40
  • 1
    +1 для изящного решения. Вы не должны перенаправлять файл хотя... –  jasonwryan 14.07.2013, 06:53
  • 2
    были на автопилоте. –  llua 14.07.2013, 17:16
  • 3
    @jasonwryan, если Вам не нужен доступ к имени файла в awk (FILENAME), это не плохая идея использовать перенаправление, поскольку это избегает проблем для имени файла, содержащего = или запуск с - (или быть -), делает для последовательных сообщений об ошибках и старается не работать awk или выполнение других перенаправлений, если входной файл не может быть открыт. –  Stéphane Chazelas 17.11.2015, 12:22

Принятие данных структурировано так, чтобы это была всегда строка прежде, и после этого Вы хотите Вас, может использовать 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"сопровождаемый любыми символами.
14
27.01.2020, 19:40
  • 1
    -C (контекст) может использоваться в качестве ярлыка, если -A и -B то же. –  David Baggerman 14.07.2013, 03:37
  • 2
    @DavidBaggerman - спасибо. Добавленный это к ответу. спасибо –  slm♦ 14.07.2013, 03:39
  • 3
    Почему тот вниз голосует? Это отвечает на вопрос. –  slm♦ 14.07.2013, 15:07

Существует, вероятно, столь же простой способ сделать это с awk, но в жемчуге:

cat file | perl -ne 'BEGIN { $/="\n\n" }; print if $_ =~ /42B/;'

Это в основном говорит, чтобы разделить файл на блоки, разграниченные пустыми строками, затем только распечатать те блоки, которые соответствуют Вашему регулярному выражению.

4
27.01.2020, 19:40

Другое решение 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
2
27.01.2020, 19:40

grep некоторых разновидностей Unix имеет флаг -p для «абзаца». Я знаю, что AIX делает .

grep -p 42B <myfile>

сделает именно то, о чем вы там просите. YMMV и GNU grep не имеют этого флага.

4
27.01.2020, 19:40

Теги

Похожие вопросы