web-dev-qa-db-ja.com

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

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

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

編集:

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

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

_program | tee >(wc -l)
_

>(cmd)はbash構文です。つまり、cmdを実行し、>(cmd)ビットをそのプログラムのSTDIN(に接続されている名前付きパイプ)へのパスに置き換えます。

44
Patrick

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

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

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

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

またはsed

program | sed -n 'p;$='
11
jordanm

Stderrでstdoutを複製できます。

program | tee /dev/stderr | wc -l

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

5
user26112

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

program | grep "" -c
3
Montells
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)
0
zlob

これは遅いかもしれません。しかし、私は変数でカウントされた数をキャッチする方法に関するあなたのフォローアップ質問に対処します。

これがYOUR_VAR=$(PROGRAM | tee /dev/stderr | wc -l)です。

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

0
huangzonghao