この出力があります。
[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
2つのチャンクがあることがわかり、最後のチャンクを抽出したいです(最初のチャンクにCPUがすべて0の場合は問題ありません)。簡単に言えば、次の最後の行を抽出したいと思います(注:時には2つ以上のインスタンスがあります。 - *)そうでない場合は、「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と可能なすべてを試しましたが、望む結果に近いものはありません。
ベストアンサー1
少し愚かな感じがしますが、次のようになります。
$ 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,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
すべての行を変数として収集し、で始まる行からその変数を消去しますvirt-top
。
ファイルが非常に大きい場合、tac
+sed
ソリューションはファイルの終わりだけを読み取る必要があるため、より高速ですが、awk
+ソリューションはファイル全体を上から読みます。