将连续流传输到多个文件

时间:2012-07-12 19:40:46

标签: linux shell awk

我有一个程序将连续运行写入输出到stdout,我想继续从它输出最后一组输出并将其写入文件。每次出现一组新的输出时,我都想覆盖同一个文件。

一个例子是以下命令:

iostat -xkd 5

每5秒打印一些输出,每个输出后都有一个空白行。我希望将最后一个“set”写入文件中,我认为这应该可以用简单的东西实现。

到目前为止,我已经尝试过使用xargs,我只能使用一行来完成此操作,而不是由一些东西划分的一组行。

我认为使用awk可能有可能,但是我无法弄清楚如何使数据缓冲,因为它可以使用系统将数据写出来,或者让它关闭并重新打开输出文件。

编辑:为了澄清,这是一个连续运行的命令。我不想启动新命令并读取它的输出。

我调整了@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)

这基本上是相同的,除了检测“section”的结尾并写入临时文件,这样每当外部进程尝试读取输出文件时,它就会完成。

3 个答案:

答案 0 :(得分:1)

部分答案:

./your_command | (while read r ; do 
    if ... ; then
        rm -f foo.out
    fi
    echo $r >> foo.out
done)

如果有条件(...),以便您知道您正在接收“套装”的第一行,这将有效。

答案 1 :(得分:0)

为什么不:

while :; do
  iostat -xkd > FILE
  sleep 5
done

如果您已开始使用awk,则以下内容会将iostat的每个输出写入编号文件:

iostat -xkd 5 | awk -v RS=$'\n'$'\n' '{ print >NR; close(NR) }'

注意:第一条记录是iostat输出的标题。

答案 2 :(得分:0)

编辑在回复评论时,我测试了这个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);

(因为显然这让人很困惑,所以剪掉了旧的答案文字)