grep -A ‹num› до появления строки

предполагая, что у нас есть файл, содержащий следующее:

chapter 1 blah blah
blah num blah num
num blah num blah
...
blah num
chapter 2 blah blah

и мы хотим выполнить grep этого файла, поэтому мы берем строки от chapter 1 blah blah до blah num (строка перед следующей главой).

Единственное, что мы знаем, это

  1. строка состояния chapter 1 blah blah
  2. где-то после этого есть еще одна строка, начинающаяся с chapter

фиктивный способ сделать это

grep -A <num> -i "chapter 1" <file>

с достаточно большим <num>, так что вся глава будет в нем.


person Giannis Tzagarakis    schedule 21.03.2015    source источник


Ответы (3)


Это легко сделать с помощью awk

awk '/chapter/ {f=0} /chapter 1/ {f=1} f' file
chapter 1 blah blah
blah num blah num
num blah num blah
...
blah num

Строка будет напечатана, если флаг f истинен.
chapter 1 и следующий за ним chapter меняют флаг.


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

awk '/chapter 1/,/chapter [^1]/ {if (!/chapter [^1]/) print}' file
chapter 1 blah blah
blah num blah num
num blah num blah
...
blah num
person Jotne    schedule 21.03.2015
comment
если предположить, что единственное, что мы знаем, это глава 1 и что где-то после нее есть глава-строка (мы знаем ее номер)? - person Giannis Tzagarakis; 21.03.2015
comment
@GiannisTzagarakis Обновлен пост, чтобы использовать следующую главу с любым номером, чтобы остановить вывод - person Jotne; 21.03.2015
comment
только потому, что я хочу анализировать большие файлы, awk кажется лучшим решением. Это быстрее, чем sed или grep. Спасибо! - person Giannis Tzagarakis; 21.03.2015
comment
Кстати, вы знаете, как передать номер главы в качестве переменной сценария bash? $num=1 awk '/chapter/ {f=0} /chapter $num/ {f=1} f' файл (awk -v n=$num '/chapter/ {f=0} /chapter n/ {f= 1} f' файл) не работает - person Giannis Tzagarakis; 21.03.2015
comment
Вот как awk -v test="$var" '/chapter/ {f=0} $0~"chapter "test {f=1} f' file. Затем просто установите var=2, и он получит главу 2. - person Jotne; 21.03.2015

Вы также можете сделать это через сам grep, но вам нужно включить параметры Perl-regexp P и z.

$ grep -oPz '^chapter 1[\s\S]*?(?=\nchapter)' file
chapter 1 blah blah
blah num blah num
num blah num blah
...
blah num

[\s\S]*? будет выполнять нежадное сопоставление нуля или более символов, пока не будет достигнута строка, в начале которой есть строка chapter.

От man grep

-z, --null-data           a data line ends in 0 byte, not newline
-P, --perl-regexp         PATTERN is a Perl regular expression
-o, --only-matching       show only the part of a line matching PATTERN
person Avinash Raj    schedule 21.03.2015

person    schedule
comment
См. комментарий ОП. Он не знает номер следующей главы. - person Jotne; 21.03.2015