3

stdoutへの出力の書き込みを継続的に実行するプログラムがあり、そのプログラムから最後の出力セットを継続的に取得して、これをファイルに書き込みたいと思います。新しい出力セットが来るたびに、同じファイルを上書きしたいと思います。

例は次のコマンドです。

iostat -xkd 5

これにより、5秒ごとに出力が出力され、各出力の後に空白行が表示されます。最後の「セット」をファイルに書き込んでもらいたいのですが、これは簡単な方法で実現できるはずだと思います。

これまで、xargsを使用してみましたが、これは、何かで区切られた行のグループではなく、1行でしか実行できませんでした。

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)

これは、「セクション」の終わりを検出して一時ファイルに書き込むことを除けば、基本的に同じであり、外部プロセスが出力ファイルを読み取ろうとするたびに完了します。

4

3 に答える 3

1

部分的な答え:

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

「セット」の最初の行を受信して​​いることがわかるような条件(...)がある場合、これは機能します。

于 2012-07-12T20:11:01.110 に答える
0

なぜだめですか:

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

以下を使用するように設定されている場合はawk、各出力をiostat番号付きファイルに書き込みます。

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

注:最初のレコードは、iostat出力するヘッダーです。

于 2012-07-12T20:13:45.397 に答える
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);

(明らかに人々を混乱させていたので、古い回答テキストを切り取った)

于 2012-07-12T20:26:33.023 に答える