Esto se siente un poco tonto, pero:
$ 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
invierte el archivo (muchos sistemas que no son GNU tienen tail -r
en su lugar), el sed
elige líneas hasta la primera que comienza con virt-top
. Puedes agregar sed 1,2d
o tail -n +3
para eliminar los encabezados.
O en 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
Simplemente recopila todas las líneas en una variable y borra esa variable en una línea que comienza con virt-top
.
Si el archivo es muy grande, el tac
+sed
La solución seguramente será más rápida ya que solo necesita leer el final del archivo mientras que el awk
solución lee el archivo completo desde la parte superior.
Con ed
puede buscar expresiones regulares hacia arriba usando ?pattern?
en lugar del habitual /pattern/
(que busca desde arriba de la posición actual). Entonces, por ejemplo:
$ 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
Si su entrada tiene un número fijo de bloques, también podría hacer algo como:
awk '/^virt-top/ && ++n == 2, 0' <your-file
Para generar las líneas de las 2 ocurrencias de virt-top
hasta el final del archivo (0 significa falso , significa el final de ese primero ,último nunca se encuentra el rango).