gnu texttoolsで連続した 'wc -l'を実行する方法は?


28

もちろん知っている

cat logfile.txt | wc -l
120

ファイル内の行数を教えてくれます。

一方、

tail -f logfile.txt

別のプログラムが書き込む新しい行を表示しlogfile.txtます。

両方を組み合わせて、標準のテキストユーティリティでlogfile.txtの継続的な更新行数を取得することは可能ですか?

私は知っています

watch wc -l logfile.txt

しかし、毎回ファイル全体を再カウントしたくないので、それは無駄だと思われます。1秒ごとに追加のみのカウントが必要になり、おそらく行末では\rなくカウントが必要になり\nます。


1
あなたのファイルは、すべてを数えるのが問題であるほど大きいですか?廃棄物に関しては、配管cat出力wcも大きな廃棄物です!!
ベルンハルト

はい、潜在的に非常に大きいです。
トウィ

回答:


36

多分:

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ですべてのシェルが組み込まれていない秒あたりのコマンド。ksh93しばらくはsleep組み込みされ、内蔵の取得するにはwc(Debianの)上に、少なくとも、あなたが追加する必要がある/opt/ast/binの前面に$PATH関係なく、かどうかの(そのディレクトリが存在するかどうか)または使用しますcommand /opt/ast/bin/wc(尋ねないでください...))。

次のように使用できますpv

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

ただし、数字が1000を超える場合はkM...接尾辞が追加されることに注意してください(そして、それを回避する方法はないようです)。


ソリューションへの方法tail | awk。あなたのオプションを知っている:-n +0この組み合わせでは私には起こらなかっただろう。
トウィ

2
おい!pv-別の便利な新しいツール。本当にありがとう。
トウィ

グレップであなたのストリームにフィルタを追加することができますtail -n +0 -f <my.log> | grep --line-buffered <mystring> | awk '{printf "\r%lu", NR}'
tombolinux

2
@tombolinuxはのawkスーパーセットですgreptail -n +0 -f file | awk '/mystring/ {printf "\r%lu", ++n}'
ステファンシャゼル14

クール。最後に印刷を改行に追加END{print ""}awkます。
pLumo

6

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

1

そのようなものがあるとは思わない。しかし、次のような方針に沿って何かを簡単に盛り上げる必要があります。

#!/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)


1
番号は、を実行するたびに増加しますprintf foo >> file。でwc -l返されたレコードではなく、改行文字をカウントする必要があります(私が提案したシェルソリューションでのように)<$fh>。私はあなたが使用する必要はないと思うtellか、seekまったく。
ステファンシャゼラス

<$fh>デフォルトでは、行を読み取り、記録していません。引用されているPerlのマンページは、おそらく非協力的な環境のためにこの方法でそれを行うように指示しています(ファイルシステムに依存する可能性があります、NFSまたは他のネットワークにマウントされたファイルシステムには多少の注意が必要かもしれません)。
フォンブランド

自分で試してみてください。ファイルの終わりに達すると<$fh>、改行文字で終了していなくてもレコードが返されます。その場合はperl、ファイルの末尾に座っている、と誰かが後でんprintf foo >> file、その後、<$fh>戻りますfoo(ないラインそれが改行文字で終了していないので)、そして$count余分な行がファイルに追加されていないにもかかわらず、インクリメントされます。
ステファンシャゼル

OPは、一度に1行ずつ書き込まれたログファイルを監視するはずでしたか?
フォンブランド

いいえ、これがソリューションが機能しない理由です。たとえば、ファイルに書き込むアプリケーションがその出力をバッファリングする場合、いつでも最後の行は終了しない可能性が高いため、2回カウントされます。
ステファンシャゼル

0

awkベースのソリューションの継続:ログの各行のカウンターティックを確認する必要がない場合があります。その場合、次のようにすることができます(10行ごとに数値が変わります)。

tail -n +0 logfile.txt | \
    awk 'a+=1{}a%10==0{printf "\r%lu", a}END{printf "\r%lu", a}'
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.