wc -l
入力がパイプに接続されたときのコマンド出力の行数を計算するためにこれを使用しています。
commad | wc -l
これはうまく機能しますが、command
計算が大幅に進行すると速度が遅くなる可能性があります。 「今までパイプされた」行数を表示する別の方法はありますか?
このようなものは、項目別の計算を行うときに特に便利です。
cat something | xargs -L1 heavy-per-line-computation | wc -l
これを手動で実行する1つの方法は、出力をファイル()にパイプしてcommand > file
定期的にcat file | wc -l
処理することです。しかし、私が望むのはコマンドです(I / Oの無駄を避けるためにファイルにリダイレクトしません)。
答え1
awk '{print NR}'
このコマンドは、見つかった行ごとに新しい番号を印刷します。最後の行が完成すると、最後の数字は話した内容と一致しますwc -l
。最後の行なら不完全その後(私のKubuntu GNUでは)awk
計算することができますが(改行文字を計算するため)違いがあるかもしれません。awk
wc -l
別の違いは、入力が完全に空の場合はwc -l
print0
であり、私たちはawk
何も印刷しないことです。印刷するには、0
次のバリアントを使用します。
awk '{print NR} END {if (NR==0) print NR}'
あるいは、各新しい番号がコンソールの同じ行にある古い番号を上書きするようにすることもできます。それからこれ:
awk '{printf "\r%s",NR} END {print "\r"NR}'
例:yes | head -n 76543 | awk '{printf "\r%s",NR} END {print "\r"NR}'
コマンドは入力を消費します(tee
おそらく便利です)。監視の目的で、次のことに興味があるかもしれません。
awk '{print NR OFS $0}'
ここで(デフォルトは空白)は(サポートされている場合)OFS
ほぼ同じです。cat -n
cat
-n
pv -l
行数を計算し、パイプライン内で使用できます。例:
for i in 1 2 3 4 5; do date; sleep 1; done | pv -l | wc -l
pv -lb
かなり小さい出力を考えてください。
答え2
Rubyを使ったソリューションです。
count_lines
stderr
stdout
最大0.5秒ごとにこれまでに受信したライン数(pass)を印刷し、最後に合計ライン数(pass)を印刷します。
read -d '' make_lines <<'EOF'
STDOUT.sync = true
[0.2, 0.1, 0.5, 0.1, 0.6, 0.1, 0.3, 0.1, 0.3, 0.01, 0.01].each do |t|
puts
sleep t
end
EOF
read -d '' count_lines <<'EOF'
lines = 0
t = 0
while gets do
lines += 1
now = Time.now.to_f
if now - t > 0.5
warn lines
t = now
end
end
puts lines
EOF
ruby -e "$make_lines" | ruby -e "$count_lines"
答え3
私はあなたが探していると思いますpv
(パイプラインビュー):
seq 100000000000 | pv -l | wc -l
答え4
CR (\r)
ほとんどの端末は「列1に移動」です。これにより、前の出力を上書きし続けることができます。
dwc
tail -f
これは、標準入力(ファイルまたは出力プロセスの置換である可能性があります)から読み取るスクリプトです。スクリプトにサンプルテストベンチがあります。
これには-l
選択が必要です。デフォルトでは、入力行番号は端末の現在の行(6桁の数字)に印刷されます。を使用すると、-l
受信した最後の行の最初の60文字を印刷し、前のテキストをすべて消去します。 EOF が表示されると、改行文字がエクスポートされ、最後の出力の下にプロンプトが表示されます。
#! /bin/bash
#.. dwc [-l]
AWK_SHORT='
BEGIN { Fmt = "\r%6d "; }
{ printf (Fmt, NR); }
END { printf ("\n"); }
'
AWK_LONG='
BEGIN { Fmt = "\r%6d %.60s"; Clr = sprintf ("%60s", ""); }
{ printf (Fmt, NR, $0 Clr); }
END { printf ("\n"); }
'
if [[ "${1}" = "-l" ]]; then
awk "${AWK_LONG}"
else
awk "${AWK_SHORT}"
fi
exit
#.. Test method.
man ls | head -n 40 |
while IFS='' read X; do
printf '%s\n' "${X}"; sleep 0.75
done |
tee >( ./dwc -l ) > foo.txt