Per essere precisi
Some text
begin
Some text goes here.
end
Some more text
e voglio estrarre l'intero blocco che inizia da "inizio" fino a "fine".
con awk possiamo fare come awk '/begin/,/end/' text
.
Come fare con grep?
Per essere precisi
Some text
begin
Some text goes here.
end
Some more text
e voglio estrarre l'intero blocco che inizia da "inizio" fino a "fine".
con awk possiamo fare come awk '/begin/,/end/' text
.
Come fare con grep?
Risposte:
Aggiornato il 18-nov-2016 (poiché il comportamento di grep è cambiato: grep con il parametro -P ora non supporta ^
e $
ancore [su Ubuntu 16.04 con kernel v: 4.4.0-21-generico]) ( correzione errata (non) )
$ grep -Pzo "begin(.|\n)*\nend" file
begin
Some text goes here.
end
nota: per altri comandi basta sostituire le ancore '^' & '$' con l'ancora di nuova linea '\n'
______________________________
Con il comando grep:
grep -Pzo "^begin\$(.|\n)*^end$" file
Se vuoi non includere i modelli "inizio" e "fine" nel risultato, usa grep con il supporto di Lookbehind e Lookahead.
grep -Pzo "(?<=^begin$\n)(.|\n)*(?=\n^end$)" file
Inoltre puoi utilizzare la \K
notifica invece dell'asserzione Lookbehind.
grep -Pzo "^begin$\n\K(.|\n)*(?=\n^end$)" file
\K
L'opzione ignora tutto prima della corrispondenza del modello e ignora il modello stesso.
\n
usato per evitare di stampare righe vuote dall'output.
O come suggerisce @AvinashRaj ci sono semplici semplici grep come segue:
grep -Pzo "(?s)^begin$.*?^end$" file
grep -Pzo "^begin\$[\s\S]*?^end$" file
(?s)
dice a grep di consentire al punto di abbinare i caratteri di nuova riga.
[\s\S]
corrisponde a qualsiasi personaggio che sia spazio bianco o non spazio bianco.
E il loro output senza includere "inizio" e "fine" è il seguente:
grep -Pzo "^begin$\n\K[\s\S]*?(?=\n^end$)" file # or grep -Pzo "(?<=^begin$\n)[\s\S]*?(?=\n^end$)"
grep -Pzo "(?s)(?<=^begin$\n).*?(?=\n^end$)" file
vedere qui il test completo di tutti i comandi ( non aggiornato poiché il comportamento grep con il parametro -P è cambiato )
^
punta l'inizio di una linea e $
punta la fine di una linea. questi sono stati aggiunti al punto "inizio" e "fine" per abbinarli se sono soli in una riga.
In due comandi sono scappato $
perché utilizzava anche "Sostituzione comando" ( $(command)
) che consente all'output di un comando di sostituire il nome del comando.
-o, --only-matching
Print only the matched (non-empty) parts of a matching line,
with each such part on a separate output line.
-P, --perl-regexp
Interpret PATTERN as a Perl compatible regular expression (PCRE)
-z, --null-data
Treat the input as a set of lines, each terminated by a zero byte (the ASCII
NUL character) instead of a newline. Like the -Z or --null option, this option
can be used with commands like sort -z to process arbitrary file names.
grep -Pzo "(?<=begin\n)(.|\n)*(?=\nend)" file
non \n
iniziasse a stampare il carattere esistente sulla riga.
grep -Pzo "(?s)begin.*?end" file
grep -Pzo "begin[\s\S]*?end" file
grep: ein nicht geschütztes ^ oder $ wird mit -Pz nicht unterstützt
la traduzione dell'errore è simile a:grep: a not protected ^ or $ is not supported with -Pz
grep
sembra essere cambiato.