grep одна строка перед матчем плюс матч

8
zzzzzzzzz
aaaaaaaaa
bbbbbbbbb &
ccccccccc &
ddddddddd
hhhhhhhhh
eeeeeeeee
fffffffff &
ggggggggg &

в приведенной выше строке я хочу, чтобы grep/ sed/ awk(любой метод в порядке) строка, которая имеет &знак плюс одна строка поверх них. так, например, желаемый результат будет выглядеть так:

aaaaaaaaa
bbbbbbbbb &
ccccccccc &
eeeeeeeee
fffffffff &
ggggggggg &

Следующее - это то, что я попробовал без удачи.

egrep "&" | -b 1 file.txt
Рана Хан
источник

Ответы:

16

Ты можешь сделать:

grep -B 1 '&$' your_file

Это будет искать строки, оканчивающиеся на &, удаляйте, $чтобы сопоставить строки с &любым положением в них.

-BПереключатель указывает grepвыводить «контекст» линии , которые идут перед строками , которые соответствуют. В этом случае, так как вы хотите одну строку контекста, вам нужно -B 1.

Этот переключатель доступен в GNU, grepно не в стандарте POSIX.

Вот простое sedрешение, которое должно помочь в случае, если у вас нет GNU grep:

sed -n '/&/!N;/&/p' your_file

Как это работает

  • -nПереключатель подавляет по умолчанию «печать» действие наsed
  • /&/!Nозначает: если текущая строка не содержит &, добавьте следующую строку в пространство шаблона.
  • /&/pозначает: сопоставить &и распечатать шаблонное пространство.
Джозеф Р.
источник
2
@RanaKhan Добро пожаловать в Stack Exchange :) Я рад, что смог помочь. Пожалуйста, не забудьте пометить этот ответ как принятый (используйте галочку под кнопками голосования рядом с ответом), если он помог решить вашу проблему, чтобы другие пользователи, просматривающие сайт, знали, что эта проблема решена.
Джозеф Р.
+1 за вариант, когда GNU/grepнедоступен, спасибо!
ckujau
3

Вот как эмулировать grep -B1с sed:

sed '$!N;/pattern/P;D' infile

Это очень похоже на тот, что здесь . Так же, как и другой, он читает в Nстроке ext, но на этот раз он Pнабирает номер первой \nстроки, если пространство образца совпадает , а затем, как и другой, Dподнимается до первой \nстроки и перезапускает цикл. Итак, с вашим примером ввода:

sed '$!N;/&/P;D' infile

выходы:

aaaaaaaaa
bbbbbbbbb &
ccccccccc &
eeeeeeeee
fffffffff &
ggggggggg &

Опять же, чтобы увидеть, как это работает, добавьте lдо и после, Nчтобы посмотреть на пространство шаблона:

sed 'l;$!N;l;/&/P;D' infile

например, с примером файла:

zzzz &
aaaa
bbbb
cccc &
dddd &
hhhh
eeee
ffff &
gggg &

это команды, которые sedвыполняются и соответствующие выходные данные:

CMD выходной CMD
l       zzzz &$               N # read in the next line
l       zzzz &\naaaa$         # pattern space matches so print up to \n
P       zzzz &                D # delete up to \n 
l       aaaa$                 N # read in the next line
l       aaaa\nbbbb$           D # delete up to \n (no match so no P)
l       bbbb$                 N # read in the next line
l       bbbb\ncccc &$         # pattern space matches so print up to \n
P       bbbb                  D # delete up to \n
l       cccc &$               N # read in the next line
l       cccc &\ndddd &$       # pattern space matches so print up to \n
P       cccc &                D # delete up to \n
l       dddd &$               N # read in the next line
l       dddd &\nhhhh$         # pattern space matches so print up to \n
P       dddd &                D # delete up to \n
l       hhhh$                 N # read in the next line
l       hhhh\neeee$           D # delete up to \n (no match so no P)
l       eeee$                 N # read in the next line
l       eeee\nffff &$         # pattern space matches so print up to \n
P       eeee                  D # delete up to \n
l       ffff &$               N # read in the next line
l       ffff &\ngggg &$       # pattern space matches so print up to \n
P       ffff &                D # delete up to \n
l       gggg &$               # last line so no N 
l       gggg &$               # pattern space matches so print up to \n
P       gggg &                D # delete up to \n
don_crissti
источник