如何使用gnu texttools连续执行'wc -l'?


28

我当然知道

cat logfile.txt | wc -l
120

会告诉我文件中的行数。

鉴于

tail -f logfile.txt

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

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

我知道

watch wc -l logfile.txt

但是我不想每次都重新计算整个文件,这似乎是浪费。一个人可能需要每秒钟左右追加一次计数,可能\r需要\n在行尾添加一个,而不是一个。


1
您的文件大到可以重述所有内容吗?在浪费方面:管道cat输出到wc也是很大的浪费!
2013年

是的,它可能很大。
towi

Answers:


36

也许:

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都内置该命令。使用ksh93while sleep内置时,要获得内置命令wc(至少在Debian上是这样),您需要/opt/ast/bin在命令前面添加$PATH(无论是否该目录存在或不存在)或使用command /opt/ast/bin/wc(不询问...))。

您可以使用pv,例如:

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

但要注意的是它增加了kM......后缀时数超过1000(和似乎没有被周围的方式)。


谁来tail | awk解决您的问题。知道您的选择:-n +0这种结合对我而言不会发生。
towi

2
pv-另一个有用的新工具。谢谢一堆。
towi

使用grep,您可以向流中添加过滤器:tail -n +0 -f <my.log> | grep --line-buffered <mystring> | awk '{printf "\r%lu", NR}'
tombolinux 2014年

2
@tombolinux awk是的超集greptail -n +0 -f file | awk '/mystring/ {printf "\r%lu", ++n}'
斯特凡Chazelas

凉。我想补充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我建议的shell解决方案一样),而不是计数的记录<$fh>。我不认为你需要使用tellseek在所有。
2013年

<$fh>读取由默认的一条线,没有记录。引用的Perl手册指出这样做是为了避免可能的不合作环境(可能取决于文件系统,我猜NFS或其他网络安装的文件系统可能需要一些提示)。
vonbrand

自己尝试,到达文件末尾时,<$fh>即使它没有以换行符终止,也会返回一条记录。因此,如果perl位于文件末尾,然后有人执行printf foo >> file<$fh>则将返回foo(不是一行,因为它没有以换行符终止),$count即使未向该文件添加任何额外的行,该行也会递增。
斯特凡Chazelas

OP应该监视一次写一行的日志文件吗?
vonbrand

不,这就是为什么您的解决方案可能无法正常工作的原因。例如,如果写入文件的应用程序缓冲了其输出,则在任何给定时间,最后一行很可能不会终止,因此将被计数两次。
斯特凡Chazelas

0

继续基于awk的解决方案:您可能不需要查看日志中每一行的计数器;就是这种情况,您可以像这样(每10行会改变一个数字):

tail -n +0 logfile.txt | \
    awk 'a+=1{}a%10==0{printf "\r%lu", a}END{printf "\r%lu", a}'
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.