Как я могу заставить 'grep' показывать одну строку на пять строк выше линии? - PullRequest
30 голосов
/ 08 июня 2011

Я видел несколько примеров опрокидывания строк до и после, но я бы хотел игнорировать средние линии. Итак, я бы хотел строку пятью линиями раньше, но больше ничего. Можно ли это сделать?

Ответы [ 4 ]

30 голосов
/ 08 июня 2011

ОК, я думаю, что это сделает то, что вы ищете. Он будет искать шаблон и извлекать 5-ю строку перед каждым совпадением.

grep -B5 "pattern" filename | awk -F '\n' 'ln ~ /^$/ { ln = "matched"; print $1 } $1 ~ /^--$/ { ln = "" }'

В основном, как это работает, он берет первую строку, печатает ее, а затем ждет, пока не увидит ^--$ (разделитель совпадений, используемый grep), и начнет снова.

10 голосов
/ 08 июня 2011

Это опция -B

   -B NUM, --before-context=NUM
    Print  NUM  lines  of  leading  context  before  matching lines.
    Places  a  line  containing  --  between  contiguous  groups  of
    matches.
9 голосов
/ 08 июня 2011

Если вы хотите, чтобы перед матчем была только 5-я строка, вы можете сделать это:

grep -B 5 pattern file | head -1

Редактировать:
Если вы можете иметь более одного матча, выможно попробовать это (обмен pattern с вашим фактическим паттерном):

sed -n '/pattern/!{H;x;s/^.*\n\(.*\n.*\n.*\n.*\n.*\)$/\1/;x};/pattern/{x;s/^\([^\n]*\).*$/\1/;p}' file

Я взял это из Sed tutorial , раздел: Удержание более одной строки в трюмебуфер , пример 2 и немного его адаптированный.

2 голосов
/ 18 февраля 2016

Этот способ мне проще:

grep --no-group-separator -B5 "pattern" file | sed -n 1~5p

Это приводит к 5 строкам перед включением шаблона, включая разделитель ---, затем печатает каждую 5-ю строку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...