Her IP adresinin günlük dosyasında kaç kez göründüğünü sayma


9

Aşağıdaki biçimde bir dosya var:

$ cat file.txt

27.33.65.2
27.33.65.2
58.161.137.7
121.50.198.5
184.173.187.1
184.173.187.1
184.173.187.1

Dosyayı aşağıdaki file.txtgibi bir formatta ayrıştırmanın en iyi yolu nedir :

27.33.65.2: 2
58.161.137.7: 1
121.50.198.5: 1
184.173.187.1: 3

Başka bir deyişle, dosyada döngü yapmak ve her IP adresinin kaç kez göründüğünü saymak istiyorum. Ben zaten sorttüm IP adresleri sırayla ve doğrudan birbiri ardına çalıştırın.


Ben şahsen, bu tür bir dosyayı yakındaki kullanışlı bir DB'ye (etrafımda bulunduğum herhangi bir postgres örneğinde geçici bir tablo oluşturarak) aktarabilir, ardından hızlı bir SQL eylemi ve bir metin dosyasına geri gönderirim.
oakad

Yanıtlar:


23

Arıyorsun uniq -c

Bunun çıktısı beğeninize göre değilse, kolayca ayrıştırılabilir ve yeniden biçimlendirilebilir.

Örneğin:

$ uniq -c logfile.txt | awk '{print $2": "$1}'
27.33.65.2: 2
58.161.137.7: 1
121.50.198.5: 1
184.173.187.1: 3

Birleştirmek uniqve awkbenim için harika bir yaklaşım gibi görünmüyor ...
Hauke ​​Laging

3
Çünkü uniqyalnızca sıralı girdi üzerinde çalışır (bitişik eşleşen satırlarla eşleşir, dosyadaki satırlarla eşleşmez).
oakad

1
Sonuçları uniqiye göndermeden önce sıralamanız gerekir. Orijinal Q'yu okursanız, OP sonuçları kullanarak halihazırda sıraladığını belirtir sort!
slm

2
@HaukeLaging - Söylediklerinizi takdir ediyorum, ancak çoğu bilgisayar kullanıcısı OSX ve Windows'un ötesinde asla girişimde bulunmayacak şekilde, ayrıca Unix kullanıcılarının çoğu belirli görevler için belirlenmiş araçları kullanmanın ötesinde girişimde bulunmayacak. AWK kullanmak kalbin zayıflığı için değildir, bu temel görevi AWK kullanarak Glenn'in çözümünün gerektirdiği şeyleri gerçekleştirmek için ne yapmanız gerektiğine bakın. Bence seninki muhtemelen daha etkili olsa da, onun zihinsel olarak anlaşılması için daha basit bir çözüm olduğunu söylerken adil davranıyorum. BTW, ikisi de doğru olduğu için UV yaptım!
slm

1
@HaukeLaging - Evet, kesinlikle. Siteyi takarken sorumluluklarımız biraz değişiyor, IMO. Kapsamlı A'ers yapmaktan ve OP'ye ve onunla karşılaşan gelecekteki her ziyaretçiye, IMO'ya öğretim anları olarak verdiğimiz A'ers'e bakmaktan sorumluyuz. Ancak kişisel bir seçimdir, bu yüzden yedeklemek için sadece birkaç dakikanız varsa, herhangi bir biçimde A sağlamak her zaman takdir edilir.
slm

6

uniqgerçekten zekice bir çözüm gibi görünüyor. Tuhaf yol:

awk '{ip_count[$0]++}; '\
'END {for (ip in ip_count) printf "%15s: %d\n",ip,ip_count[ip];}' file

+1. Çıktının sırası OP için önemliyse, bu cevap herhangi bir garanti vermez: ilişkilendirilebilir bir dizinin anahtarları üzerinden yineleme doğal bir sıraya sahip değildir.
glenn jackman

@glennjackman Ancak cevabımı eklemek sortdaha az öğe sıralanması gerektiğinden hala daha hızlı. ;-)
Hauke ​​Laging

Ah evet? AH EVET?!? ;) giriş zaten sıralanmıştır. Bu garip cevap onları karıştırır, bu yüzden daha fazla iştir. Nyah! ;)
glenn jackman

0

firest sıralama dosyası sonra unic -c ile saymak

sort filename | uniq -c


1
Dosya zaten sıralanmıştır (söz konusu kullanıcıya göre) ve uniq -cişe yarar ancak çıktıyı yanlış biçimde sağlar. Bu nedenle kabul edilen cevap kullanılmaz sortve çıktısını yeniden biçimlendirir uniq -c.
Kusalananda

Teşekkürler @Aeyd. Bu komutu arıyordum.
Yardımcı

0

Python kullanırdım. Günümüzde her linux gövdesi python2 yüklüdür.

Her ip adresini bir dikteye (ilişkilendirilebilir dizi) anahtar = değer çiftleri olarak ekleyin, örneğin {"12.34.56.78": 1, "87.76.43.21": 3}.

IP adresini anahtar olarak 'doğrular' ve değeri 1 arttırırsınız. Defaultdict ("ip") kullanırsanız, anahtar yoksa, varsayılan 0 değeriyle oluşturulur. zaten, defaultdict hiçbir şey yapmaz. Değer bir sonraki satırda artırılır.

#!/usr/bin/python2

infile = open("file.txt","r")
iplist = {}  # create an empty dict

for line in infile:
    line = line.strip()   # remove newline.
    if line: # if not a blank line.
        iplist.setdefault(line, 0) # check for ip and add with default value of 0
        iplist[line] += 1 # increment

outfile = open("out.txt","w") #open output file

for key in iplist.keys():
    line = "%-15s = %s" % (key, iplist[key])
    print line   # print uf desired.
    outfile.write(line + "\n")

çıkış dosyası:

cat out.txt                                                          
27.33.65.2      = 2
58.161.137.7    = 1
121.50.198.5    = 1
184.173.187.1   = 3

Bir komut satırı çözümü aradığınızı biliyorum, ancak gördüğünüz gibi, sadece bir düzine satır alan zarif bir şekilde biçimlendirilmiş bir ekran. Python yönetim için mükemmel bir araçtır.

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.