2014-07-11 11 views

risposta

8

Questo potrebbe funzionare per voi (GNU SED):

sed 'H;/pattern/h;$!d;x;//!d' file 

stashes l'ultimo modello e seguenti righe nello spazio stiva e alla fine del file stampe fuori.

O utilizzando lo stesso metodo in awk:

awk '{x=x ORS $0};/pattern/{x=$0};END{if(x ~ //)print x}' file 

Tuttavia sulla mia macchina jaypals strada con sed sembra essere il più veloce:

tac file | sed '/pattern/q' | tac 
7

Reverse il file, stampa fino a quando il primo modello, uscire e invertire il file.

tac file | awk '/pattern/{print;exit}1' | tac 
2

Ecco un modo la Perl per farlo:

perl -ne '$seen = 1, @a =() if /pattern/; push @a, $_; END { print @a if $seen }' file 
1

A awk standalone: ​​

awk '/pattern/{delete a;c=0}{a[c++]=$0}END{for (i=0;i<c;i++){print a[i]}}' file 
2

soluzione più semplice è solo quello di utilizzare una corrispondenza regex su tutto il file:

perl -0777 -ne 'print $1 if /pattern(.*?)$/' file 
0

Ecco un puro awk

awk 'FNR==NR {if ($0~/pattern/) f=FNR;next} FNR==f {a=1}a' file{,} 

legge il file due volte, e la prima volta per impostare un flag ultima trovata di pattern, poi sotto forma di stampa pattern e fuori.


Oppure è possibile memorizzare i dati in un array come questo:

awk '/pattern/ {f=NR} {a[NR]=$0} END {for (i=f;i<=NR;i++) print a[i]}' file 
0

Utilizzando GNU awk per RS ​​multi-char e gensub():

$ awk -v RS='^$' -v ORS= '{print gensub(/.*(pattern)/,"\\1","")}' file 

ad esempio:

$ cat file 
a 
b 
c 
b 
d 

$ awk -v RS='^$' -v ORS= '{print gensub(/.*(b)/,"\\1","")}' file 
b 
d 

Quanto sopra cancella semplicemente dall'inizio del file fino a poco prima dell'ultima occorrenza di "b".