O grep geralmente é usado em arquivos orientados a linhas. De quando em vez aparece algo mais complicado.
Se precisamos de mais contexto, podemos usar -B (before) e -A (after) para indicar quantas linhas queremos de antes e depois do que for encontrado:
grep -B 4 -A 3 ERROR log.txt
E assim podemos ver 3 linhas para frente e 4 para trás.
Se o arquivo tiver delimitadores, podemos usar uma mágica do Perl. Considere o arquivo abaixo:
Registro 1
Nome: Fulano
Endereço: Rua Torta, 1
Sexo: M
Fim
Registro 2
Nome: Beltrana
Endereço: Rua Reta, 12
Sexo: F
Fim
Se eu quiser filtrar todos os registros com "Sexo: F", posso usar a variável $/, que indica o que é um separador de linha.
$ perl -ne "BEGIN{$/='Fim'} print if /Sexo: F/" pessoas.txt
Registro 2
Nome: Beltrana
Endereço: Rua Reta, 12
Sexo: F
$ perl -ne "BEGIN{$/='Fim'} print if /Sexo: M/" pessoas.txt
Registro 1
Nome: Fulano
Endereço: Rua Torta, 1
Sexo: M
O BEGIN serve para executarmos a atribuição apenas uma vez, porque a opção -n coloca tudo dentro de um "while(<>) {}". Mas se não nos importamos com isso, podemos simplificar com:
perl -ne "$/='Fim'; print if /Sexo: M/" pessoas.txt
Podemos até incluir o \n no valor de $/ para não surgirem linhas vazias nos resultados. Para isso, também temos usar o qq() (quoted string) para não termos problemas com as aspas duplas:
perl -ne "$/=qq(Fim\n); print if /Sexo: M/" pessoas.txt
Se os registros não tiverem os mesmos terminadores ou se o arquivo contiver outras estruturas que não nos interessam, podemos usar o operador flip-flop:
#!/usr/bin/perl
open(my $file, '<', $ARGV[0]);
my ($block, $found);
while(<$file>) {
if(/^Registro/ .. /^Fim/) {
$found=1 if /Sexo: M/;
$block.=$_;
} else {
print $block if $found;
undef $block;
$found=0;
}
}
print $block if $found;
Esse script recebe o nome do arquivo como parâmetro. A mágica acontece no "if(/^Registro/ .. /^Fim/)". O operador começa a retornar verdadeiro quando encontra Registro e passa a retornar falso quando encontra Fim. O resto do arquivo cai no else. O resto do script é óbvio.
Então, temos 3 opções para buscas progressivamente complexas em arquivos. Perl, como de costume, salva o dia.
Nenhum comentário:
Postar um comentário