Pagina 1 di 1
Grep Multiline matching
Inviato: dom 16 apr 2006, 0:18
da h8er
ciao avrei una domanda da farvi, grep supporta il matching di espressioni regolari su più linee ?? mi spiego, dato un file di testo così fatto
:::nome1
linea\n
linea\n
linea\n
:::nome2
linea\n
linea\n
linea\n
:::nome3
linea\n
linea\n
linea\n
ecc ecc.. ora io vorrei catturare ad esempio tutte le linee da :::nome2 al seguente ::: con powergrep per windows riesco a trovare correttamente le varie linee con un espressione del tipo
ma in grep gnu non funziona.. sapete aiutarmi ?? non ditemi che non si puo' :'(
Inviato: dom 16 apr 2006, 10:59
da alessiodf
Codice: Seleziona tutto
cat file.txt | awk -v FS="\n" -v RS='' '/:::nome2/{print $0}'
Dove file.txt è in tuo file... e la parte /:::nome2/ è il record che vuoi ricavare... in questo caso viene:
Codice: Seleziona tutto
alessio@skynet[~]$ cat a.txt | awk -v FS="\n" -v RS='' '/:::nome2/{print $0}'
:::nome2
linea\n
linea\n
linea\n

Potentissimo AWK!
Volendo puoi addirittufa prendere solamente alcune delle "linea/n".. certo, forse è sprecato usare awk...ma non mi veniva altro in mente!

Inviato: dom 16 apr 2006, 14:24
da Paoletta
se conosci il numero delle linee che ti interessano puoi sfruttare l'opzione -A
Inviato: dom 16 apr 2006, 20:37
da targzeta
alessiodf ha scritto:Codice: Seleziona tutto
cat file.txt | awk -v FS="\n" -v RS='' '/:::nome2/{print $0}'
Ci tengo a dire che:
1) Si può eliminare la pipeline in questo modo:
Codice: Seleziona tutto
awk -v FS="\n" -v RS='' '/:::nome2/{print $0}' file.txt
2) Questo comando non fa esattamente quello richiesto perchè in una situazione come questa:
Codice: Seleziona tutto
:::nome2
linea
linea
linea
:::nome3
linea
linea
linea
non funzionerebbe. Provare per credere!
awk è potente...se lo sai usare

.
In alternativa, visto che neanche io so esattamente se con grep si può fare (prego h8er di farlo sapere se riesce a scoprire come), si può usare questo comando
Codice: Seleziona tutto
sed -n '/:::nome2/{b label;};d;:label /:::.*:::/{x;p;q;};{h;N;b label}' file.txt
per non scomodare awk.
Se vuoi sapere esattamente cosa fa questo script per sed te lo posso spiegare in dettaglio. Non lo faccio ora perchè
verrebbe un post lungo ed ho constatato che i post lunghi molto spesso vengono ignorati (fatica sprecata insomma)

.
Spina
Inviato: dom 16 apr 2006, 21:09
da alessiodf
spina ha scritto:
2) Questo comando non fa esattamente quello richiesto perchè in una situazione come questa:
Codice: Seleziona tutto
:::nome2
linea
linea
linea
:::nome3
linea
linea
linea
non funzionerebbe. Provare per credere!
awk è potente...se lo sai usare

.
Bhe..certo.. ti assicuro che awk lo so usare bene.. e serve per la scansione e la ricerca nei
record... quello che hai scritto tu cos'è??? e' solamente un file di testo, ma quello che ha proposto h8er è un'altra cosa...!
Inviato: lun 17 apr 2006, 2:41
da h8er
grazie a tutti per avermi risposto in particolare a spina per avermi fatto notare sed con la sua sintassi, in realtà l'esempio era semplificato poichè in realtà devo trovare nello stesso file più linee tra i tag ::: ::: e sopratutto il "nome2" non è unico ma me lo posso ritrovare in stringhe più complicate comunque ho risolto così (non è finissima la cosa ed è ampiamente ottimizzabile ma fa il suo sporco lavoro, assembly rulez :twisted: )
Codice: Seleziona tutto
sed -n ':label1 /:::.*nome2.*/{p;:label2 n; /:::/ !{p;b label2;};b label1;};n; b label1;' file
PS: per grep mi sa proprio che non supporta il matching multilinea ma lo fa alla grande sed quindi direi che non c'è problema
