如何使用 gnu texttools 执行连续的“wc -l”?

如何使用 gnu texttools 执行连续的“wc -l”?

我当然知道

cat logfile.txt | wc -l
120

会告诉我文件中的行数。

然而

tail -f logfile.txt

将向我显示另一个程序写入的新行logfile.txt

是否可以将两者结合起来,以便我使用标准文本实用程序获得 logfile.txt 的连续更新行数?

我确实知道

watch wc -l logfile.txt

但我不想每次都重新计算整个文件,这似乎是一种浪费。人们需要每秒左右进行一次仅附加计数,并且可能需要在行尾使用 a\r而不是 a 。\n

答案1

或许:

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

请注意,它会为每行输入输出一个数字(但如果发送到终端,则会覆盖先前的值)。

或者你可以tail -f在 shell 中手动实现:

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

(请注意,它每秒最多运行一个wc又一个sleep命令,并非所有 shell 都内置了该命令。使用ksh93whilesleep是内置的,要获得内置命令wc(至少在 Debian 上),您需要/opt/ast/bin在前面添加$PATH(无论是否该目录是否存在)或使用command /opt/ast/bin/wc(不要问...))。

您可以使用pv,如:

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

但请注意,当数字超过 1000 时,它会添加k, ... 后缀(并且M似乎没有办法解决这个问题)。

答案2

bash尝试用 pure without来计数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}'

相关内容