Abaixo está o texto no arquivo:
Pseudo name=Apple
Code=42B
state=fault
Pseudo name=Prance
Code=43B
state=good
Eu preciso grep para "42B" e obter a saída do texto acima, como:
Pseudo name=Apple
Code=42B
state=fault
Alguém tem idéia de como conseguir isso usando grep
/ awk
/ sed
?
Respostas:
Com
awk
RS=
altera o separador de registro de entrada de uma nova linha para linhas em branco. Se algum campo de um registro contiver,/42B/
imprima o registro.''
(a cadeia nula) é um valor mágico usado para representar linhas em branco de acordo com o POSIX :Os parágrafos de saída não serão separados, pois o separador de saída permanece uma única nova linha. Para garantir que haja uma linha em branco entre os parágrafos de saída, configure o separador de registros de saída para duas novas linhas:
fonte
FILENAME
), não é uma má idéia usar o redirecionamento, pois evita problemas para o nome de arquivo que contém=
ou começa com-
(ou está sendo-
), gera mensagens de erro consistentes e evita executarawk
ou executar outros redirecionamentos se o arquivo de entrada não puder ser aberto.Supondo que os dados sejam estruturados para que seja sempre a linha antes e depois do desejado, você pode usar os switches grep
-A
(after) e-B
(before) para dizer para incluir a 1 linha antes da partida e 1 linha depois:Se você deseja as mesmas linhas numéricas antes e depois do termo de pesquisa, pode usar a opção
-C
(context):Se você deseja ser mais rigoroso ao corresponder às várias linhas, pode usar a ferramenta
pcregrep
, para corresponder a um padrão em várias linhas:O padrão acima corresponde da seguinte forma:
-M
- várias linhas'Pseudo.*\n.*42B.*\nstate.*'
- corresponde a um grupo de cadeias de caracteres em que a primeira cadeia começa com a palavra"Pseudo"
seguida por qualquer caractere até o final da linha\n
, seguida de qualquer caractere até a sequência"42B"
seguida de qualquer caractere até outro final da linha (\n
), seguida pela sequência"state"
seguido por qualquer caractere.fonte
-C
(contexto) pode ser usado como atalho, se-A
e-B
for o mesmo.Provavelmente existe uma maneira igualmente fácil de fazer isso com o awk, mas no perl:
Basicamente, isso significa dividir o arquivo em pedaços delimitados por linhas em branco e depois imprimir apenas os pedaços que correspondem à sua expressão regular.
fonte
cat
;perl -00 -ne 'print if /42B/' file
O
grep
de alguns sabores do Unix tem a-p
bandeira de "paragraph". Eu sei que o AIX faz .faria exatamente o que você está pedindo lá. O YMMV e o GNU grep não têm esse sinalizador.
fonte
Uma outra solução perl, sem uma linha vazia à direita:
Exemplo
fonte
perl -00 -ne 'print if /42B/' file
.