Bash Komut Dosyası: dosyadaki benzersiz satırları sayın


129

Durum:

Birkaç saatlik ağ yakalamasından elde edilen IP adreslerini ve bağlantı noktalarını içeren büyük bir dosyam (milyonlarca satır) var, her satırda bir ip / bağlantı noktası. Çizgiler şu biçimdedir:

ip.ad.dre.ss[:port]

İstenen sonuç:

Günlük kaydı sırasında aldığım her paket için bir giriş var, bu yüzden çok sayıda yinelenen adres var. Bunu, biçimin satırlarına indirgeyebilecek bir tür kabuk betiği aracılığıyla çalıştırabilmek istiyorum.

ip.ad.dre.ss[:port] count

countbu belirli adresin (ve bağlantı noktasının) gerçekleşme sayısı nerede . Özel bir çalışma yapılmasına gerek yoktur, farklı bağlantı noktalarını farklı adresler olarak ele alın.

Şimdiye kadar, tüm ip adreslerini günlük dosyasından kazımak için bu komutu kullanıyorum:

grep -o -E [0-9]+\.[0-9]+\.[0-9]+\.[0-9]+(:[0-9]+)? ip_traffic-1.log > ips.txt

Bundan, adresim tarafından gönderilen (umursamadığım) tüm ip adreslerini kazımak için oldukça basit bir normal ifade kullanabilirim.

Daha sonra benzersiz girişleri çıkarmak için aşağıdakileri kullanabilirim:

sort -u ips.txt > intermediate.txt

Satır sayılarını bir şekilde sıralama ile nasıl toplayabileceğimi bilmiyorum.

Yanıtlar:


303

uniqSıralanmış tekrarlanan satırların sayısını almak için komutu kullanabilirsiniz :

sort ips.txt | uniq -c

En sık sonuçları en üstte almak için (Peter Jaric'e teşekkürler):

sort ips.txt | uniq -c | sort -bgr

10
Ne kadar -bgrtesadüfen bir anımsatıcı gibi göründüğünü seviyorum bigger, üstte istediğimiz şey bu.
dwanderson

1
Sizin için küçük bir işlevi olarak .bashrcveya .bash_aliasesdosyaya: function countuniquelines () { sort "$1" | uniq -c | sort -bgr; }. Tarafından arayın countuniquelines myfile.txt.
Johan

Neden emin değilim sort -nr.
Nakilon

5

To saymak benzersiz toplam satır sayısını (yani yinelenen satırları düşünmediğini) kullanabileceğimiz uniqveya Awk wc:

sort ips.txt | uniq | wc -l
awk '!seen[$0]++' ips.txt | wc -l

Awk dizileri ilişkiseldir, bu yüzden sıralamadan biraz daha hızlı çalışabilir.

Metin dosyası oluşturuluyor:

$  for i in {1..100000}; do echo $RANDOM; done > random.txt
$ time sort random.txt | uniq | wc -l
31175

real    0m1.193s
user    0m0.701s
sys     0m0.388s

$ time awk '!seen[$0]++' random.txt | wc -l
31175

real    0m0.675s
user    0m0.108s
sys     0m0.171s

İlginç. Büyük veri kümeleri için kayda değer bir fark yaratabilir
Wug

1

Bu, tekrarlanan satırların sayısını elde etmenin ve en az sıklıkta en sık olana doğru güzelce yazdırılmasını sağlamanın en hızlı yoludur:

awk '{!seen[$0]++}END{for (i in seen) print seen[i], i}' ips.txt | sort -n

Performansı önemsemiyorsanız ve hatırlaması daha kolay bir şey istiyorsanız, o zaman çalıştırın:

sort ips.txt | uniq -c | sort -n

Not:

sort -n alanı bir sayı olarak ayrıştırır, bu doğrudur çünkü sayıları kullanarak sıraladığımız için.


!İçinde {!seen[$0]++}sadece az baskı yaptığı gibi, burada gereksiz END.
Amir
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.