Linux

從底部提取行直到正則表達式匹配

  • September 11, 2019

我有這個輸出。

[root@linux ~]# cat /tmp/file.txt
virt-top time  11:25:14 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.0  0.0  96:02:53 instance-0000036f
   2 R    0    0    0    0  0.0  0.0  95:44:07 instance-00000372
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

你可以看到它有兩個塊,我想提取最後一個塊(如果你看到第一個塊,它的 CPU 全部為零,我不在乎)簡而言之,我想提取最後幾行(注意:有時我有兩個以上的實例-*) 否則我可以使用“tail -n 2”

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

我已經嘗試了 sed/awk/grep 和所有可能的方法,但沒有接近期望的結果。

這感覺有點傻,但是:

$ 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

GNUtac反轉文件(許多非 GNU 系統有tail -r),sed選擇行直到第一個以virt-top. 您可以添加sed 1,2dtail -n +3刪除標題。

或者在 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

它只是將所有行收集到一個變數中,並在以virt-top.

如果文件很大,tac+sed解決方案肯定會更快,因為它只需要讀取文件的尾部,而awk解決方案從頂部讀取整個文件。

引用自:https://unix.stackexchange.com/questions/540029