Sürekli 'wc -l' gnu texttools ile nasıl yapılır?


28

Tabii ki biliyorum

cat logfile.txt | wc -l
120

bana bir dosyadaki satır sayısını söyleyecektir.

Buna karşılık

tail -f logfile.txt

bana başka bir programın yazdığı yeni satırları gösterecek logfile.txt.

Her ikisini de birleştirmek mümkün mü böylece logfile.txt dosyasının sürekli güncellenen satır sayısını standart metin yardımcı programlarıyla alabilir miyim?

Hakkında bilgim var

watch wc -l logfile.txt

ancak her seferinde tüm dosyayı tekrar saymak istemiyorum, bu israf gibi görünüyor. İnsanın her saniye ya da öylesine eklenmiş bir sayıma ve muhtemelen satırın sonundaki \ryerine bir sayıma ihtiyacı olacaktır \n.


1
Dosyanız her şeyi anlatan kadar büyük bir problem mi? Atık açısından: boru catçıkışı wcda büyük bir atıktır !!
Bernhard

Evet, potansiyel olarak çok büyük.
towi

Yanıtlar:


36

Olabilir:

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

Her giriş satırı için bir sayı vereceğine dikkat edin (bir terminale gönderilen önceki değeri geçersiz kılar).

Veya tail -felle kabuğunu uygulayabilirsiniz :

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

(not o birine kadar çalıştığı wcve bir sleepile bütün kabuklar içinde yerleşik olmayan saniyede komuta. ksh93süre sleepyerleşik olan, bir yerleşik olsun wc(Debian) üzerinde en azından, eklemek gerekir /opt/ast/binönünde $PATHbakılmaksızın arasında ( bu dizin var veya yok) veya kullan command /opt/ast/bin/wc(sorma ...)).

Aşağıdaki gibi kullanabilirsiniz pv:

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

Ama eklediği dikkat k, Msayısı 1000'e (ve ne zaman ... eklerini o etrafında bir yol olarak görünmüyor ).


tail | awkÇözümünüzü kime . Seçeneklerinizi bilin: -n +0bu kombinasyonda başıma gelmezdi.
towi

2
whoo! pv- başka bir kullanışlı yeni araç. çok teşekkürler.
towi

Grep ile akışınıza bir filtre ekleyebilirsiniz:tail -n +0 -f <my.log> | grep --line-buffered <mystring> | awk '{printf "\r%lu", NR}'
tombolinux

2
@ tombolinux, awkbir süperset grep. tail -n +0 -f file | awk '/mystring/ {printf "\r%lu", ++n}'
Stéphane Chazelas

Güzel. Ben eklemek END{print ""}yapmak için awksonunda bir yeni satır yazdırın.
pLumo

6

Saf basholmadan saymaya çalışın wc:

a=0 ; tail -f file | while read -r line ; do ((a++)) ; echo $a ; done

veya önceki değeri yeniden yazmak için bile böyle:

a=0 ; tail -f file | while read -r line ; do ((a++)) ; echo -ne "\r$a" ; done

1

Bunun gibi bir şey olduğuna inanmıyorum. Ancak, çizgileri boyunca bir şey kırbaçlamak kolay olmalıdır:

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

(Genel fikir kaynağından toplandı perlfunc(1))


1
Her yaptığınızda sayı artar printf foo >> file. Newline karakterlerini ( wc -lönerdiğim kabuk çözümünde olduğu gibi) saymanız gerekiyor , döndürdüğünüz kayıtları değil <$fh>. Senin kullanman gerektiğini tellya da seekhiç kullandığını sanmıyorum .
Stéphane Chazelas,

<$fh>Varsayılan olarak bir çizgi okur kaydeder değil. Alıntı yapılan Perl sayfası, işbirlikçi olmayan bir ortam uğruna bu şekilde yapılmasını söyler (dosya sistemine bağlı olabilir, sanırım NFS ya da ağa bağlı diğer dosya sistemleri biraz prodding gerektirebilir).
vonbrand

Kendiniz deneyin, dosyanın sonuna gelindiğinde <$fh>yeni satır karakteriyle sonlandırılmamış olsa bile bir kayıt döndürür. Yani eğer perldosyanın sonunda oturuyor ve birisi daha sonra bir yok printf foo >> file, sonra <$fh>geri döner foo(bir değil çizgi bir satır karakteri ile sonlandırılır değil çünkü) ve $counthiçbir ekstra hat dosyaya eklenir olsa bile artırılır.
Stéphane Chazelas

OP bir kerede bir satır yazılmış logfiles izlemek gerekiyordu?
vonbrand

Hayır, bu yüzden çözümünüz çalışmayabilir. Örneğin, dosyaya yazılan uygulamalar çıktısını tamponlarsa, herhangi bir zamanda, son satırın sonlandırılmaması muhtemeldir, bu nedenle iki kez sayılır.
Stéphane Chazelas

0

Awk tabanlı çözüme devam etme: günlüğünüzdeki her satır için sayaç işaretlemesini görmenize gerek olmayabilir; durum böyle, buna sahip olabilirsiniz (her 10 satır için sayı değişebilir):

tail -n +0 logfile.txt | \
    awk 'a+=1{}a%10==0{printf "\r%lu", a}END{printf "\r%lu", a}'
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.