我有一个程序将连续运行写输出到标准输出,我想不断从它的最后一组输出,并将其写入一个文件。 每次有一组新的输出,我想覆盖相同的文件。
一个例子是以下命令:
iostat -xkd 5
每5秒钟打印一些输出,每一个输出一个空行。 我希望最后的“集合”被写入一个文件,我认为这应该可以通过一些简单的事情来实现。
到目前为止,我已经尝试过使用xargs,我只能用一行代码来完成这个工作,而不是由一些由某些东西划定的行。
我认为这可能与awk,但我不知道如何让它缓冲数据,因为它可以写出它使用系统,或让它closures并重新打开相同的输出文件。
编辑 :澄清,这是一个连续运行的单一命令。 我不想开始一个新的命令,并阅读它的输出。
解
我调整了@Bittrance的答案来得到以下结果:
iostat -xkd 5 | (while read r; do if [ -z "$r" ]; then mv -f /tmp/foo.out.tmp /tmp/foo.out else echo "$r" >> /tmp/foo.out.tmp fi done)
这基本上是相同的,除了检测“部分”的结束和写入临时文件,以便每当外部进程试图读取输出文件将完成。
部分答案:
./your_command | (while read r ; do if ... ; then rm -f foo.out fi echo $r >> foo.out done)
如果有一个条件(…),以便你知道你正在接收“set”的第一行,这将工作。
为什么不:
while :; do iostat -xkd > FILE sleep 5 done
如果您使用awk
设置,则以下内容将iostat
每个输出写入一个编号文件:
iostat -xkd 5 | awk -v RS=$'\n'$'\n' '{ print >NR; close(NR) }'
注意:第一个记录是iostat
输出的标题。
编辑在回复评论,我测试了这个Perl解决方案的工作:
#!/usr/bin/perl use strict; use warnings; $|=1; open(STDOUT, '>', '/tmp/iostat.running') or die $!; while(<>) { seek (STDOUT, 0, 0) if (m/^$/gio); print }
所以,现在你可以
iostat -xkd 5 | myscript.pl&
并观看快照:
watch -n10 cat /tmp/iostat.running
如果你想确保最后有足够的空间被覆盖(因为每次输出的长度可能会有所不同),你可以在最后打印一些填充,例如:
print "***"x40 and seek (STDOUT, 0, 0) if (m/^$/gio);
(剪下旧的答案文本,因为显然这是令人困惑的人)