Gnu texttoolsを使用して連続 "wc -l"を実行する方法は?

Gnu texttoolsを使用して連続 "wc -l"を実行する方法は?

当然知っている

cat logfile.txt | wc -l
120

ファイルの行数を通知します。

しかし、

tail -f logfile.txt

他のプログラムで作成した新しい行が表示されますlogfile.txt

標準のテキストユーティリティを使用して、連続的に更新されるlogfile.txt行数を取得できるように、2つを組み合わせることができますか?

私も知っています

watch wc -l logfile.txt

しかし、毎回ファイル全体を再計算したくありません。無駄のように見えます。毎秒追加の専用カウントを実行する必要があり、行の\r末尾にaの代わりにaを使用する必要があります。\n

答え1

おそらく:

tail -n +1 -f file | awk '{printf "\r%lu", NR}'

各入力行の数字を出力します(ただし、端末に送信されると前の値を上書きします)。

または、tail -fシェルで手動で実行することもできます。

n=0
while :; do 
  n=$(($n + $(wc -l)))
  printf '\r%s' "$n"
  sleep 1
done < file

(毎秒最大1つのwcコマンドを実行し、sleepすべてのシェルにこの機能が組み込まれているわけではありません。whileを使用すると、組み込みコマンドを取得できます(ksh93少なくともsleepDebianwcでは)。 .))./opt/ast/bin$PATHcommand /opt/ast/bin/wc

次のものを使用できますpv

tail -n +1 -f file | pv -bl > /dev/null

ただし、1000個を超えるとk、...接尾辞(およびMこの問題には方法がないようです。)。

答え2

bash次のことなく純粋に計算してみてくださいwc

a=0 ; tail -f file | while read -r line ; do ((a++)) ; echo $a ; done

または、次のように古い値を上書きすることもできます。

a=0 ; tail -f file | while read -r line ; do ((a++)) ; echo -ne "\r$a" ; done

答え3

私はそのようなものがあると信じていません。ただし、次の作業は簡単です。

#!/usr/bin/perl

$for_a_while = 1;

$oldcount = -1;
$count = 0;
open($fh, "<", $ARGV[0]);

for (;;) {
  for ($curpos = tell($fh); <$fh>; $curpos = tell($fh)) {
    $count++;
  }
  if($count != $oldcount) {
    print "$count\n";
    $oldcount = $count;
  }
  sleep($for_a_while);
  seek($fh, $curpos, 0);
}

(一般的なアイデアはからコピーされますperlfunc(1)

答え4

awkベースのソリューションを引き続き使用すると、ログ内のすべての行に対してカウンタを表示する必要はありません。この場合、次のように設定できます(数字は10行ごとに変更されます)。

tail -n +0 logfile.txt | \
    awk 'a+=1{}a%10==0{printf "\r%lu", a}END{printf "\r%lu", a}'

関連情報