grep -ozP "(?s)(abc)[^(abc)]*(mno)" 1
abc
yyy
mno
abc
xxx
mno
Eu tenho uma entrada como abaixo. Quero descobrir tudo, começando com abc
e terminando com mno
, incluindo linhas entre, mas se abc
aparecer novamente antes de mno
, quero ignorar o primeiro abc
correspondente. A ideia é que eu só preciso de um grupo que comece com abc
e termine com mno
que estão mais próximos uns dos outros.
test.txt
contém os dados abaixo:
abc bbb abc yyy mno abc xxx mno
Resultado esperado:
abc yyy mno abc xxx mno
Estou usando o abaixo de grep
liner:
grep -ozP "(?s)(abc).\*?(mno)" test.txt
O resultado é:
abc bbb abc yyy mno abc xxx mno
As duas primeiras linhas não devem estar lá na saída. Por favor, informe o que eu posso modificar em grep
para obter o resultado desejado.
Uma maneira de fazer isso é inverter o arquivo usando tac
, encontrar correspondências iniciando com mno
e terminando com abc
e reverter isso para obter o resultado desejado. Eu tenho o seguinte para trabalhar:
$ tac test.txt | pcregrep -M 'mno(\n|.)*?abc' | tac
abc
yyy
mno
abc
xxx
mno
(Estou usando pcregrep
para o sinalizador multilinha -M
)
Apenas no caso de o perl ser uma opção para você:
#!/usr/bin/env perl
# saved lines to print out
my @out = ();
# should we save lines?
my $saving = 0;
while (<>) {
if (/abc/) {
if ($saving) {
# this is the second /abc/, so dump what we were saving and start over
@out = ($_);
} else {
# this is the first /abc/, so save it and start saving lines
push @out, $_;
$saving = 1;
}
} elsif (/mno/) {
if ($saving) {
# print what we've saved, plus this /mno/ ending line, then reset
print @out, $_;
@out=();
$saving=0;
}
} else {
# otherwise, save lines if we should be
push @out, $_ if $saving;
}
}
Tags grep