W dużej mierze polegałem na pcregrep, ale w nowszym grep nie musisz instalować pcregrep dla wielu jego funkcji. Po prostu użyj grep -P
.
W przykładzie pytania PO myślę, że następujące opcje działają dobrze, a drugi najlepiej pasuje do tego, jak rozumiem pytanie:
grep -Pzo "abc(.|\n)*efg" /tmp/tes*
grep -Pzl "abc(.|\n)*efg" /tmp/tes*
Skopiowałem tekst jako / tmp / test1 i usunąłem „g” i zapisałem jako / tmp / test2. Oto wynik pokazujący, że pierwszy pokazuje pasujący ciąg, a drugi pokazuje tylko nazwę pliku (typowe -o ma pokazywać dopasowanie, a typowe -l pokazuje tylko nazwę pliku). Zauważ, że „z” jest konieczne dla multilinii, a „(. | \ N)” oznacza dopasowanie „cokolwiek innego niż nowa linia” lub „nowa linia” - tj. Cokolwiek:
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
Aby ustalić, czy Twoja wersja jest wystarczająco nowa, uruchom man grep
i sprawdź, czy coś podobnego do tego pojawia się u góry:
-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.
To pochodzi z GNU grep 2.10.