Как сделать непрерывный wc -l с текстовыми инструментами gnu?

Я знаю, конечно, что

cat logfile.txt | wc -l 120 

скажет мне количество строк в файле.

В то время как

 tail -f logfile.txt 

покажет мне новые строки, которые другая программа записывает в logfile.txt .

Можно ли комбинировать оба так, чтобы я получал непрерывное количество строк обновления logfile.txt со стандартными текстовыми утилитами?

Я знаю о

 watch wc -l logfile.txt 

но я не хочу перечитывать весь файл каждый раз, что кажется пустым. Каждому нужно было бы подсчитать количество секунд или около того и, возможно, \r вместо \n в конце строки.

4 Solutions collect form web for “Как сделать непрерывный wc -l с текстовыми инструментами gnu?”

Может быть:

 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 

(обратите внимание, что он запускает до одной команды wc и one sleep в секунду, которые не все встроенные оболочки. С ksh93 когда sleep ksh93 , чтобы получить встроенный wc (по крайней мере, на Debian), вам нужно добавить /opt/ast/bin в начале $PATH (независимо от того, существует ли этот каталог или нет) или используйте command /opt/ast/bin/wc (не спрашивайте …)).

Вы можете использовать pv , как в:

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

Но будьте осторожны, что он добавляет k , M … суффиксы, когда число превышает 1000 (и , похоже, это не так ).

Попытайтесь считать это чистым 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 

Я не верю, что есть что-то в этом роде. Но это должно быть легко взломать что-то вроде:

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

Продолжение решения на основе awk: вам может не понадобиться видеть отметку счетчика для каждой строки в вашем журнале; это так, вы можете иметь это как это (число изменилось бы на каждые 10 строк):

 tail -n +0 logfile.txt | \ awk 'a+=1{}a%10==0{printf "\r%lu", a}END{printf "\r%lu", a}' 
  • Захват вывода команды bash, анализ и сохранение в разные переменные bash
  • xargs repl_str не расширяет второй заполнитель
  • Какой из них работает быстрее - обычные операторы (такие как <,>, =) или используя (-lt, -gt, -eq)? и почему?
  • Расписание (Cron), выполняющее задачи на основе сценариев bash с использованием CronniX
  • ImageMagick для нескольких файлов
  • sed работает при вводе из эха, но не из файла
  • удалить завершающие нули в awk не работает. ошибка синтаксиса
  • Как выполнить инструкцию IF из результата выполненной команды
  • Как написать сценарий для подсчета общего количества файлов и каталогов в моем домашнем каталоге, а затем отобразить его?
  • Загрузите файл на сервер?
  • Как вычесть строки, наоборот, только если больше, чем предыдущая строка
  • Linux и Unix - лучшая ОС в мире.