Jak wyszukać wzorzec wielowierszowy w pliku?

Musiałem znaleźć wszystkie pliki, które zawierały określony wzór łańcucha. Pierwsze rozwiązanie, które przychodzi na myśl, to użycie find piped with xargs grep :

find . -iname '*.py' | xargs grep -e 'YOUR_PATTERN'

Ale jeśli muszę znaleźć wzory, które obejmują więcej niż jedną linię, utknąłem, ponieważ vanilla grep nie może znaleźć wzorów wielowierszowych.

Author: Reinstate Monica Please, 2008-09-30

11 answers

Dlaczego nie pójdziesz na awk :

awk '/Start pattern/,/End pattern/' filename
 106
Author: Amit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-04 03:45:30

Więc odkryłem pcregrep co oznacza Zgodne z Perlem wyrażenia regularne GREP .

Na przykład, musisz znaleźć pliki, w których zmienna ' _name 'jest natychmiast następująca po zmiennej' _description ':

find . -iname '*.py' | xargs pcregrep -M '_name.*\n.*_description'

Wskazówka: musisz dołączyć znak podziału linii do wzorca. W zależności od platformy może to być '\N', \ r', '\r\n',...

 101
Author: Oli,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-02 07:44:26

Oto przykład użycia GNU grep:

grep -Pzo '_name.*\n.*_description'

-z/--null-data traktuj dane wejściowe i wyjściowe jako sekwencje linii.

Zobacz też tutaj

 92
Author: ayaz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-12-03 17:15:27

grep -P używa również libpcre, ale jest dużo szerzej zainstalowane. Aby znaleźć kompletną sekcję title dokumentu html, nawet jeśli obejmuje ona wiele linii, możesz użyć tego:

grep -P '(?s)<title>.*</title>' example.html

Ponieważ Projekt PCRE implementuje do standardu perl, użyj dokumentacji Perla w celach informacyjnych:

 21
Author: bukzor,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-26 18:47:20

Oto bardziej przydatny przykład:

pcregrep -Mi "<title>(.*\n){0,5}</title>" afile.html

Przeszukuje znacznik title w pliku html, nawet jeśli obejmuje do 5 linii.

Oto przykład nieograniczonych linii:

pcregrep -Mi "(?s)<title>.*</title>" example.html 
 20
Author: Oli,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-12-03 18:09:15

With silver searcher :

ag 'abc.*(\n|.)*efg'

Optymalizacje prędkości silver searcher może zabłysnąć tutaj.

 8
Author: Shwaydogg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-13 21:05:33

Możesz użyć alternatywy grep sift tutaj (zastrzeżenie: jestem autorem).

Obsługuje dopasowanie Wielowierszowe i ograniczenie wyszukiwania do określonych typów plików po wyjęciu z pudełka:

sift -m --files '*.py' 'YOUR_PATTERN'

(Przeszukaj wszystkie pliki*. py pod kątem podanego wzorca regex wielowierszowego)

Jest dostępny dla wszystkich głównych systemów operacyjnych. Spójrz na stronę próbek , aby zobaczyć, jak można jej użyć do wyodrębnienia wartości wielowierszowych z pliku XML.

 4
Author: svent,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-22 22:50:03

@Marcin: przykład awk:

awk '{if ($0 ~ /Start pattern/) {triggered=1;}if (triggered) {print; if ($0 ~ /End pattern/) { exit;}}}' filename
 3
Author: Martin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-23 13:53:13

Ta odpowiedź może być przydatna:

Regex (grep) for multi-line search needed

Aby znaleźć rekurencyjnie można użyć flags - r (recursive) oraz --include (GLOB pattern). Zobacz:

Użyj składni grep --exclude / --include, aby nie używać grep przez określone pliki

 3
Author: albfan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-05 13:19:16
perl -ne 'print if (/begin pattern/../end pattern/)' filename
 2
Author: pbal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-04 01:27:25

Za pomocą ex/vi editor and globstar option (składnia podobna do awk i sed):

ex +"/string1/,/string3/p" -R -scq! file.txt

Gdzie aaa jest punktem wyjścia, a {[7] } jest tekstem końcowym.

Aby wyszukać rekurencyjnie, spróbuj:

ex +"/aaa/,/bbb/p" -scq! **/*.py

uwaga: aby włączyć składnię **, Uruchom shopt -s globstar (Bash 4 lub zsh).

 2
Author: kenorb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-15 01:30:35