Sembra un po' sciocco, ma:
$ tac file.txt |sed -e '/^virt-top/q' |tac
virt-top time 11:25:17 Host foo.example.com x86_64 32/32CPU 1200MHz 65501MB
ID S RDRQ WRRQ RXBY TXBY %CPU %MEM TIME NAME
1 R 0 0 0 0 0.6 12.0 96:02:53 instance-0000036f
2 R 0 0 0 0 0.2 12.0 95:44:08 instance-00000372
GNU tac inverte il file (molti sistemi non GNU hanno tail -r invece), il sed seleziona le righe fino alla prima che inizia con virt-top . Puoi aggiungere sed 1,2d o tail -n +3 per rimuovere le intestazioni.
O in awk:
$ awk '/^virt-top/ { a = "" } { a = a $0 ORS } END {printf "%s", a}' file.txt
virt-top time 11:25:17 Host foo.example.com x86_64 32/32CPU 1200MHz 65501MB
ID S RDRQ WRRQ RXBY TXBY %CPU %MEM TIME NAME
1 R 0 0 0 0 0.6 12.0 96:02:53 instance-0000036f
2 R 0 0 0 0 0.2 12.0 95:44:08 instance-00000372
Raccoglie tutte le righe in una variabile e cancella quella variabile su una riga che inizia con virt-top .
Se il file è molto grande, il file tac +sed soluzione è destinata ad essere più veloce poiché deve solo leggere la coda del file mentre il awk soluzione legge il file completo dall'alto.
Con ed puoi cercare con espressioni regolari verso l'alto utilizzando ?pattern? al posto del solito /pattern/ (che cerca dall'alto la posizione corrente). Quindi, ad esempio:
$ printf '%s\n' '?ID?+1,$p' q | ed -s file.txt
1 R 0 0 0 0 0.6 12.0 96:02:53 instance-0000036f
2 R 0 0 0 0 0.2 12.0 95:44:08 instance-00000372
Se il tuo input ha un numero fisso di blocchi puoi anche fare qualcosa del tipo:
awk '/^virt-top/ && ++n == 2, 0' <your-file
Per emettere le righe dalla seconda occorrenza di virt-top alla fine del file (0 significa falso , indica la fine di quel primo ,ultimo range non viene mai trovato).