2010-04-12 2 views
5

Ho un file che è simile a questo:Bash: (? Forse sed) Estrarre Gamma con regolare Expressioin

<many lines of stuff> 
SUMMARY: 
<some lines of stuff> 
END OF SUMMARY 

Voglio estrarre solo le cose tra il SUMMARY e END OF SUMMARY. Sospetto di poterlo fare con sed, ma non sono sicuro di come. So che posso modificare le cose in mezzo a questo:

sed "/SUMMARY/,/END OF SUMMARY/ s/replace/with/" fileName 

(Ma non sono sicuro di come estrarre quella roba).

Sono Bash su Solaris.

risposta

8
sed -n "/SUMMARY/,/END OF SUMMARY/p" fileName 
+1

corrisponde a questo anche: .... SINTESI .... FINE DI SINTESI Aggiunta '^' di richiedere corrispondente alla stringa nulla all'inizio del pattern space: sed -n "/^RIEPILOGO /,/^ FINE RIEPILOGO/p " –

+1

Se lo fai, probabilmente è una buona idea aggiungere anche un marcatore di fine riga.Vale a dire: "sed -n"/^ SOMMARIO $ /,/^ FINE DEL RIASSUNTO $/p "' – sixtyfootersdude

1

Se Perl va bene è possibile utilizzare:

perl -e 'print $1 if(`cat FILE_NAME`=~/SUMMARY:\n(.*?)END OF SUMMARY/s);' 
+0

Sì, mi piace perl troppo ma la mia squadra sono le persone più Seddy. – sixtyfootersdude

+0

Anche a me piace il Perl, ma questo suona molto più come un lavoro per sed. –

0

Si può fare questo con awk:

$ echo 'many 
lines 
of 
stuff 
SUMMARY: 
this is the summary 
over two lines 
END OF SUMMARY' | awk ' 
    BEGIN    {e=0} 
    /^END OF SUMMARY$/ {e=0} 
         {if (e==1) {print}} 
    /^SUMMARY:$/  {e=1}' 

che uscite:

this is the summary 
over two lines 

Non tutti implementat gli ioni di awk richiedono la clausola BEGIN ma mi piace sempre includere l'inizializzazione esplicita.

Funziona utilizzando un flag di eco (e) per decidere se ci si trova nella sezione di riepilogo o meno.

1

Se non si desidera stampare le linee marcatore:

sed '1,/SUMMARY/d;/END OF SUMMARY/,$d' filename 
0

Su Solaris, utilizzare nawk

#!/bin/bash 
nawk ' 
/SUMMARY/{ 
gsub(".*SUMMARY:",""); 
f=1 
} 
/END OF SUMMARY/{f=0; 
gsub("END OF SUMMARY.*","") 
}f' file 

uscita

$ cat file 
1 2 3 <many lines of stuff> 
4 5 6 SUMMARY: 7 8 9 
<some lines of stuff> 
END OF SUMMARY blah 
blah 

$ ./shell.sh 
7 8 9 
<some lines of stuff> 
1

Questo dovrebbe funzionare utilizzando (FreeBSD) sed pure:

sed -E -n -e '/^SUMMARY:/,/^END OF SUMMARY/{ /^SUMMARY:/d; /^END OF SUMMARY/d; p;}' file.txt 
+0

Qual è il vantaggio di questo rispetto a 'sed -n"/^ SOMMARIO $ /,/^ FINE DEL RIASSUNTO $/p "fileName'? – sixtyfootersdude

0

Ecco l'ennesima versione sed solo facendo una stampa a più linee & smettere (che può essere adatto per l'estrazione di una gamma di linee da un file di grandi dimensioni):

sed -E -n -e '/^SUMMARY:$/{n;h;};/^END OF SUMMARY$/!H;/^END OF SUMMARY$/{g;p;q;}' fileName | sed 1d 

per un multi-linea di sed sceneggiatura abbastanza ben spiegato vedere:

http://ilfilosofo.com/blog/2008/04/26/sed-multi-line-search-and-replace/

+0

Hum. Ho dato un'occhiata a quel riferimento, ma continuo a pensare che è meglio fare sostituzioni utilizzando un intervallo piuttosto che i buffer. Interessato a sapere se/perché pensi che i buffer siano migliori. – sixtyfootersdude