`wc -l`代替は、行が受信されたときの数を示します。

`wc -l`代替は、行が受信されたときの数を示します。

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計算することができますが(改行文字を計算するため)違いがあるかもしれません。awkwc -l

別の違いは、入力が完全に空の場合はwc -lprint0であり、私たちは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 -ncat-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_linesstderrstdout最大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に移動」です。これにより、前の出力を上書きし続けることができます。

dwctail -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

関連情報