Come posso cercare un modello multilinea in un file?
-
02-07-2019 - |
Domanda
Avevo bisogno di trovare tutti i file che contenevano uno schema di stringhe specifico. La prima soluzione che mi viene in mente sta usando trova convogliato con xargs grep :
find . -iname '*.py' | xargs grep -e 'YOUR_PATTERN'
Ma se devo trovare schemi che si estendono su più di una riga, sono bloccato perché greilla vaniglia non riesce a trovare schemi multilinea.
Soluzione
Così ho scoperto pcregrep che sta per GREP per le espressioni regolari compatibili Perl .
Ad esempio, devi trovare i file in cui la variabile ' _name ' è immediatamente seguita dalla variabile ' _description ':
find . -iname '*.py' | xargs pcregrep -M '_name.*\n.*_description'
Suggerimento: è necessario includere il carattere di interruzione di riga nel modello. A seconda della piattaforma, potrebbe essere '\ n', \ r ',' \ r \ n ', ...
Altri suggerimenti
Perché non scegli awk :
awk '/Start pattern/,/End pattern/' filename
grep -P
usa anche libpcre, ma è molto più ampiamente installato. Per trovare una sezione completa title
di un documento html, anche se si estende su più righe, puoi usare questo:
grep -P '(?s)<title>.*</title>' example.html
Poiché il progetto PCRE implementa lo standard perl, utilizzare la documentazione perl come riferimento:
Ecco un esempio più utile:
pcregrep -Mi "<title>(.*\n){0,5}</title>" afile.html
Cerca il tag del titolo in un file html anche se si estende su 5 righe.
Ecco un esempio di linee illimitate:
pcregrep -Mi "(?s)<title>.*</title>" example.html
Con cercatore d'argento :
ag 'abc.*(\n|.)*efg'
Le ottimizzazioni di velocità di Silver Searcher potrebbero probabilmente brillare qui.
Puoi utilizzare l'alternativa grep setacciare qui (dichiarazione di non responsabilità: sono l'autore).
Supporta la corrispondenza multilinea e la limitazione della ricerca a tipi di file specifici pronti all'uso:
sift -m --files '*.py' 'YOUR_PATTERN'
(cerca tutti i file * .py per il modello regex multilinea specificato)
È disponibile per tutti i principali sistemi operativi. Dai un'occhiata alla pagina degli esempi per vedere come può essere usata per estrarre valori multilinea da un File XML.
Questa risposta potrebbe essere utile:
Regex (grep) per la ricerca multi-riga necessaria
Per trovare ricorsivamente puoi usare i flag -R (ricorsivo) e --include (modello GLOB). Vedi:
Usa grep --exclude / - include la sintassi per non eseguire il grep attraverso determinati file
perl -ne 'print if (/begin pattern/../end pattern/)' filename
Utilizzo dell'editor ex
/ vi
e opzione globstar (sintassi simile a awk
e sed
):
ex +"/string1/,/string3/p" -R -scq! file.txt
dove aaa
è il punto di partenza e bbb
è il testo finale.
Per cercare ricorsivamente, prova:
ex +"/aaa/,/bbb/p" -scq! **/*.py
Nota: per abilitare la sintassi **
, esegui shopt -s globstar
(Bash 4 o zsh).
@Marcin: esempio awk non avido:
awk '{if (<*> ~ /Start pattern/) {triggered=1;}if (triggered) {print; if (<*> ~ /End pattern/) { exit;}}}' filename