Eu confiei muito no pcregrep, mas com o grep mais recente, você não precisa instalar o pcregrep para muitos de seus recursos. Apenas usegrep -P
.
No exemplo da pergunta do OP, acho que as seguintes opções funcionam bem, com a segunda melhor correspondência de como eu entendo a pergunta:
grep -Pzo "abc(.|\n)*efg" /tmp/tes*
grep -Pzl "abc(.|\n)*efg" /tmp/tes*
Copiei o texto como / tmp / test1 e excluí o 'g' e salvei como / tmp / test2. Aqui está a saída que mostra que o primeiro mostra a sequência correspondente e o segundo mostra apenas o nome do arquivo (típico -o é para mostrar correspondência e típico -l é para mostrar apenas nome do arquivo). Observe que o 'z' é necessário para a multilinha e o '(. | \ N)' significa corresponder 'qualquer coisa que não seja nova linha' ou 'nova linha' - ou seja, qualquer coisa:
user@host:~$ grep -Pzo "abc(.|\n)*efg" /tmp/tes*
/tmp/test1:abc blah
blah blah..
blah blah..
blah blah..
blah efg
user@host:~$ grep -Pzl "abc(.|\n)*efg" /tmp/tes*
/tmp/test1
Para determinar se sua versão é nova o suficiente, execute man grep
e veja se algo semelhante a esse aparece na parte superior:
-P, --perl-regexp
Interpret PATTERN as a Perl regular expression (PCRE, see
below). This is highly experimental and grep -P may warn of
unimplemented features.
Isso é do GNU grep 2.10.