前のプログラムからの出力行数をカウントする

特定のプログラムが生成する出力行数をカウントしようとしています。問題はプログラムです。実行に時間がかかり、出力をユーザーに表示したい。最後のコマンドが出力した行数をカウントする方法はありますか?

program | wc -lを実行できましたが、出力がユーザーに表示されませんでした。私の知る限り、program; program | wc -lを実行する必要がありますが、プログラムの実行には少なくとも1分かかるため、2回以上実行する必要はありません。下部に行数を表示します。

編集:

  • 出力が発生したときに(1行ずつ)表示し、最後にカウントを返す方法はありますか?

コメント

  • どうですか:プログラムに自身の出力を追跡させ、変数からその値を読み取るだけです(例: STDOUT_WRITE_COUNT)、またはプログラムの最後にファイル/ APIに記録します。WDYT?

回答

teeを使用して、出力ストリームを分割し、1つのコピーをwcに送信してもう1つは通常のようにSTDOUTにコピーします。

program | tee >(wc -l) 

>(cmd)はbash構文で、ruを意味します。 n cmdそして、>(cmd)ビットをそのプログラムのSTDIN(に接続された名前付きパイプ)へのパスに置き換えます。

コメント

  • >(cmd)ksh構文であり

およびbashであり、' tには/dev/fd/nがあります。

  • @StephaneChazelasはい、ほとんどのシェルでサポートされていますが、'にはありません。 POSIXなので、'どこにでもあるとは限りません。
  • はい、プロセス置換は答えの文言としての発明は、信じさせることができます。
  • @TheLibbster効率的な定義方法によって異なります。この方法では、2つの追加プロセスを生成する必要がありますが、sedawkは1つだけです。ただし、teewcはどちらも非常に小さい(sed
  • )。

  • @TheLibbsterはい、私が行ったいくつかの簡単なテストによると、'は実際には約2倍の速さですsedメソッドとawkメソッドの両方として。 (dd 100mbの/dev/urandomをファイルに追加し、そのファイルを各メソッドで数回実行しました)
  • 回答

    1つのオプションは、カウントを実行してstdoutに出力できるawkを使用することです。

    program | awk "{ print } END { print NR }" 

    awkでは、NRは現在の行番号です。 perlでも同じことができます:

    program | perl -pe "END {print "$.\n"}" 

    またはsed

    program | sed -n "p;$=" 

    コメント

    • 出力を(行ごとに)表示し、最後にカウントを返す方法はありますか? ?

    回答

    私のお気に入りのオプション:

    program | grep "" -c 

    コメント

    • OPが他の質問をした可能性がありますが、出力された行数のカウントを取得するためだけにここに来ましたが、'実際の出力を表示する必要はありませんが、これで問題ありません。ありがとう!

    回答

    stderrでstdoutのクローンを作成できます。

    program | tee /dev/stderr | wc -l 

    このように、program“のstdoutはteeにパイプされ、stderrに書き込まれます。コンソールに出力されます。teeは、それにパイプされたデータをstdoutに書き込み、stdoutはwcにパイプされます。

    回答

    これは遅れる可能性があります。ただし、変数でカウントされた数を取得する方法についてのフォローアップの質問に対処します。

    これが必要なものですYOUR_VAR=$(PROGRAM | tee /dev/stderr | wc -l)

    teeを利用して、ここで2つのストリームを生成します。 1つを画面に表示される/dev/stderrに転送し、もう1つをwc -lに転送して行数を報告します。

    回答

    tail -f /var/log/squid/access.log | ( c=0; pl() { echo $c; c=0; }; trap pl SIGHUP; while read a; do (( c=c+1 )); done ) & ( trap "kill $! ; exit" SIGINT; trap "" SIGHUP; while true; do kill -HUP $! ; sleep 1; done) 

    コメントを残す

    メールアドレスが公開されることはありません。 * が付いている欄は必須項目です