Як показувати рядки після кожного поєднання грепу до іншого конкретного матчу?


44

Я знаю, що за допомогою "-A NUM"перемикача я можу надрукувати певну кількість кінцевих ліній після кожного матчу. Мені просто цікаво, чи можна друкувати прорисовані рядки, поки не знайдеться певне слово після кожного матчу. Наприклад, коли я шукаю "Word A", я хочу бачити рядок, що містить "Word A", а також рядки після нього, поки не буде "Word D".

контекст:

Word A
Word B
Word C
Word D
Word E
Word F

команда:

grep -A10 'Word A'

Мені потрібен цей вихід:

Word A
Word B
Word C
Word D

Відповіді:


73

Здається, ви хочете друкувати рядки між ' Word A' і ' Word D' (включно). Я пропоную вам використовувати sedзамість цього grep. Це дозволяє редагувати діапазон вхідного потоку, який починається і закінчується потрібними візерунками. Вам слід просто сказати sedнадрукувати всі рядки в діапазоні і жодних інших рядків:

sed -n -e '/Word A/,/Word D/ p' file

Будь-які поради, як зробити його ексклюзивним (для будь-якої загальної ситуації, а не лише для ОП)?
2rs2ts

4
@ 2rs2ts, щоб зробити його ексклюзивним, просто додайте | sed -e '1d;$d', тобто видалити перший і останній рядок
holroy

І якщо ви хочете виключити всі рядки між собою - тобто ви хочете просто побачити лінії, які знаходяться поза двома збігами, - тоді: sed -n -e '/pattern A/,/pattern D/d; p'Це говорить: "видаліть із шаблону А до шаблону D і надрукуйте все інше". На жаль, цей матч жадібний. Це означає, що якщо шаблони A і D з'являються не один раз, ви збираєтеся відповідати від першого шаблону A до останнього шаблону D. Я боюся, що Perl або Python - ваші друзі, якщо це так.
fbicknel

16

чому б не використовувати awk?

awk '/Word A/,/Word D/' filename

2
Здається, sed може зробити це набагато ефективніше, якщо задіяна велика кількість файлів. awk може бути легше запам’ятати, але sed, здається, вартує наліпки в моєму мозку.
JimNim

1
awk є кращим, якщо він Word Dпотрапляє на ту саму лінію Word A, що і, можливо, в іншому місці, наприклад, Word A Word D\nWord Dз sed покаже дві лінії, де, як awk, покаже одну. Додатково все ще можна використовувати змінні з awk, наприклад awk -v _word="Word A" '$0 ~ _word,/Word D/' "/some/file", так sed може бути більш ефективним, але при роботі з пошуком двох рядків, які можуть або не можуть потрапити на одну лінію, awk, безумовно, буде більш надійним.
S0AndS0

здається , що AWK краще обробляє випадок , що файл містить послідовності Aі , Bі ви тільки хочете , щоб захопити те , що між кожною такою послідовністю. схоже, sed не притримується цієї семантики в моєму випадку.
Матан

9
perl -lne 'print if /Word A/ .. /Word D/' file

або

cat file | perl -lne 'print if /Word A/ .. /Word D/'

1
+1, щоб протидіяти поворотному повороту. Я все одно використовую sedдля цього, якщо вам не потрібна сила регулярних виразів Perl для вибору розділових ліній.
tripleee

Люди, які писали sed в 70-х, повинні бути вдячні :-)
Matan
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.