我当然知道
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 都内置了该命令。使用ksh93
whilesleep
是内置的,要获得内置命令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}'