Sat*_*ish 5 linux command-line sed awk regular-expression
我有这个输出。
[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
Run Code Online (Sandbox Code Playgroud)
你可以看到它有两个块,我想提取最后一个块(如果你看到第一个块,它的 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
Run Code Online (Sandbox Code Playgroud)
我已经尝试了 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
Run Code Online (Sandbox Code Playgroud)
GNUtac反转文件(许多非 GNU 系统都有tail -r),sed选择行直到第一个以virt-top. 您可以添加sed 1,2d或tail -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
Run Code Online (Sandbox Code Playgroud)
它只是将所有行收集到一个变量中,并清除以virt-top.
如果文件非常大,tac+sed解决方案肯定会更快,因为它只需要读取文件的尾端,而awk解决方案从顶部读取整个文件。