grep uma linha antes da partida mais a partida

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

na linha acima, o que eu quero é a grep/ sed/ awk(qualquer método é bom) linha que tem &sinal mais uma linha em cima deles. por exemplo, a saída desejada será semelhante a:

aaaaaaaaa
bbbbbbbbb &
ccccccccc &
eeeeeeeee
fffffffff &
ggggggggg &

A seguir, é o que tentei sem sorte.

egrep "&" | -b 1 file.txt
Rana Khan
fonte

Respostas:

16

Você pode fazer:

grep -B 1 '&$' your_file

Isso procurará as linhas que terminam em &, remova $para combinar as linhas com &qualquer lugar nelas.

O -Bswitch informa greppara a saída de linhas de "contexto" anteriores às linhas correspondentes. Nesse caso, como você deseja uma linha de contexto, é necessário -B 1.

Essa opção está disponível no GNU, grepmas não está no padrão POSIX.

Aqui está uma sedsolução simples que deve ajudar caso você não tenha o GNU grep:

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

Como funciona

  • A -nopção suprime a ação "impressão" padrão desed
  • /&/!Nsignifica: se a linha atual não contiver &, acrescente a próxima linha ao espaço do padrão.
  • /&/psignifica: combinar &e imprimir o espaço do padrão.
Joseph R.
fonte
2
@RanaKhan Bem-vindo ao Stack Exchange :) Estou feliz por poder ajudar. Não se esqueça de marcar esta resposta como aceita (use a marca de seleção abaixo dos botões de votação ao lado da resposta) se ela ajudou a resolver seu problema, para que outras pessoas que navegam no site saibam que esse problema foi resolvido.
Joseph R.
+1 para a variante quando GNU/grepnão estiver disponível, obrigado!
ckujau 16/02
3

Veja como emular grep -B1com sed:

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

É muito parecido com o daqui . Assim como o outro, ele lê na Nlinha ext, mas desta vez, ele Pcria a primeira linha de \new se o espaço do padrão corresponder e, assim como o outro, Delimina a primeira linha de \new e reinicia o ciclo. Assim, com sua entrada de amostra:

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

saídas:

aaaaaaaaa
bbbbbbbbb &
ccccccccc &
eeeeeeeee
fffffffff &
ggggggggg &

Novamente, para ver como ele funciona, adicione lantes e depois do Npara observar o espaço do padrão:

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

por exemplo, com um arquivo de amostra:

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

estes são os comandos que são sedexecutados e a saída correspondente:

cmd saída 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
fonte