繰り返し実行時に正しく動作するように、スクリプトでプログラムによって生成された使用量出力の合計をどのように実装しますか?

繰り返し実行時に正しく動作するように、スクリプトでプログラムによって生成された使用量出力の合計をどのように実装しますか?

プログラムによってデータが制限されるパイプを持つスクリプトがあります。 20分ごとにスループット状態を送信する標準エラー、ファイルにリダイレクトします。

command | cstream -t -512k -T 1200 -B 64m 2>>/home/user/totals.log | command

SIGUSR1信号を次に送信することもできます。ストリームメディアkill -s 10 PID)これは私が行ったように間隔を設定し、ファイルに1行を追加したときと同じ出力を生成します。アイデアは、間隔を設定し、要求時に状態を照会できることです。出力形式は次のとおりです。ファイル全体に空白文字が1つだけあり、改行文字で終わります。

...
1931255808 B 1.8 GB 3683.6 s (1:01 h) 524289 B/s 512.00 KB/s
2560401408 B 2.4 GB 4883.6 s (1:21 h) 524289 B/s 512.00 KB/s
3189547008 B 3.0 GB 6083.6 s (1:41 h) 524289 B/s 512.00 KB/s
3818692608 B 3.6 GB 7283.6 s (2:01 h) 524289 B/s 512.00 KB/s
4447838208 B 4.1 GB 8483.6 s (2:21 h) 524289 B/s 512.00 KB/s
10829824 B 10.3 MB 20.65 s 524487 B/s 512.19 KB/s

データの進行状況を確認できますが、各列の合計(または平均)を計算することはできません。この例では、イベントは2つ(ライン1-5、6)のみなので、スクリプトを2回使用します。偶然に最後の2行を追加できるようになりました。なぜなら再起動し、その瞬間のスナップショットがあるからです。しかし、それはランダムです。その結果、コマンドを終了して再開すると、最後の行に示すようにカウンタがリセットされます。

目標は、時間の経過とともに開始するスクリプトのすべてのインスタンスのステータス出力の累積合計を取得することです。私は通常、一度に複数のインスタンスを起動しません。だから私のスクリプトに以下を追加しようとしています(「通常」はスクリプトの1つのインスタンスにのみ適用されます)。

  • まず、ログの最後の行を除くすべてのエントリを削除してください。
  • 最後に、スクリプトが終了したらログにステータスを書き込むようにします。
    • 最初の行と最後の行の各列の合計/平均
    • すべての中間行を削除します。

ドットがつながれなくてすみません。私が望むものをデザインして実装する最も簡単で良い方法は何ですか?複雑さは利点よりも重要ですか?ログデータがいっぱいになったときに単純なコマンドを使用してログデータを操作することに集中する必要がありますか?

答え1

まあ、あなたが示した内容に基づいてかなり安定して分類できましたが、このデータには深刻な問題があります。珍しい。あなたは人間に優しいここの値は良くありません。たとえば、最初の行と最後の行のMB違いGB- 処理は次のようになります。たくさん追加の作業を行う必要はありません。バイト数だけを計算してはいけませんか?ここで何が起こっているのでしょうか([h]:[mm])?なぜ最後の行ではなく最初の行にあり、なぜUnixの時間ではないのですか?

正直なところ、これは記録すべきデータがまったくなく、あまり役に立ちません。もちろん、読みやすくなりますが、10,000行を読むことはできますか?私の考えでは、あなたが望んでいないようで質問をすることです。その出力を変更する必要があります。文字をまったく取得せず、エポック以降のバイト数と秒数だけを取得するだけです。これにより、たくさんあなたにとっては簡単です。

今私が言うのはまさにそれです。したする:

set -- $(
sed '$bl;1H;d;:l;x;G
     s/([1-9][^)]*) //;h
     s/\n/First:&       /
     s/[^:]\(\n\)/&Last:\1      /
     w /dev/fd/2
     g' <<\DATA
1931255808 B 1.8 GB 3683.6 s (1:01 h) 524289 B/s 512.00 KB/s
2560401408 B 2.4 GB 4883.6 s (1:21 h) 524289 B/s 512.00 KB/s
3189547008 B 3.0 GB 6083.6 s (1:41 h) 524289 B/s 512.00 KB/s
3818692608 B 3.6 GB 7283.6 s (2:01 h) 524289 B/s 512.00 KB/s
4447838208 B 4.1 GB 8483.6 s (2:21 h) 524289 B/s 512.00 KB/s
10829824 B 10.3 MB 20.65 s 524487 B/s 512.19 KB/s
DATA
)

最初のsed行は、最初の行と最後の行を取得して編集するsedために同じパターンスペースに配置するために必要なすべてです。各行の前には\n行文字が続きます。このステートメントは、次のすべての操作を実行します。

$bl;1H;d;:l;x;G

次の行は、問題の一部であるデータの奇妙なタイムアウトを消去し、古いスペースにh結果の追加コピーを保存します。

s/([1-9][^)]*) //;h

次の3行に単語を挿入してください。最初:そして最後:次に、その行の前に\newlineと<tab>文字を追加して結果を作成しますstderr

 s/\n/First:&       /
 s/[^:]\(\n\)/&Last:\1      /
 w /dev/fd/2

最後のsed行は、前のスペースgから2番目のコピーを取得し、h現在のパターンスペースを上書きし、最後のパターンスペースを印刷し、sed別の行を印刷する基本的な操作を実行します\n。もちろん、現在の結果はあまり印象的ではありません。上記のスクリプトを実行すると、次のような結果が出力されます。

First:
        1931255808 B 1.8 GB 3683.6 s 524289 B/s 512.00 KB/s
Last:
        10829824 B 10.3 MB 20.65 s 524487 B/s 512.19 KB/s

しかし、意図的にset結果をシェル配列に入れました。そしてsed何らかの理由で、これらの2行はのパターンスペースから引き続きアクセスできます。たとえば、最後の行にg沿って行くとsed(必要に応じて)、次のようなパターン空間を使用できます。

\n1931255808 B 1.8 GB 3683.6 s 524289 B/s 512.00 KB/s\n10829824 B 10.3 MB 20.65 s 524487 B/s 512.19 KB/s$ 

または、そのままにしておくと、すでに存在する項目に次のものを追加できます。

printf '%s LINE, FIELDs 1 and 2: %s and %s' \
    FIRST "$1" "$2" LAST "${11}" "${12}"

出力は次のようになります。

FIRST LINE, FIELDs 1 and 2: 1931255808 and B
LAST LINE, FIELDs 1 and 2: 10829824 and B

stderrこれはすでに提供されている出力に追加されます。

関連情報