Menghitung berapa kali setiap alamat IP muncul dalam file log

9

Saya memiliki file dalam format sebagai berikut:

$ 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

Apa cara terbaik untuk mem-parsing file file.txtke dalam format seperti:

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

Dengan kata lain, saya ingin mengulang-ulang file dan menghitung berapa kali setiap alamat IP muncul. Saya sudah menjalankannya sortsehingga semua alamat IP dalam urutan dan langsung setelah satu sama lain.

James Spittal
sumber
Saya, secara pribadi, akan mengimpor file semacam ini ke dalam DB terdekat yang berguna (dengan membuat tabel temp pada setiap postgres yang saya dapatkan), diikuti oleh tindakan SQL cepat dan ekspor kembali ke file teks.
oakad

Jawaban:

23

Kamu sedang mencari uniq -c

Jika hasilnya tidak sesuai dengan keinginan Anda, itu bisa diurai dan diformat ulang dengan mudah.

Sebagai contoh:

$ 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
glenn jackman
sumber
Menggabungkan uniqdan awktampaknya bukan pendekatan yang bagus untuk saya ...
Hauke ​​Laging
3
Karena uniqhanya berfungsi pada input yang diurutkan (cocok dengan baris yang cocok yang berdekatan, bukan baris apa pun dari file).
oakad
1
Anda harus mengurutkan hasilnya sebelum mengirimnya ke uniq. Jika Anda membaca Q asli, OP menyatakan bahwa ia sudah mengurutkan hasilnya menggunakan sort!
slm
2
@ HaukeLaging - Saya menghargai apa yang Anda katakan tetapi dengan cara yang sama bahwa sebagian besar pengguna komputer tidak akan pernah berani melampaui OSX & Windows, lebih jauh lagi sebagian besar pengguna Unix tidak akan berani menggunakan alat yang ditunjuk untuk tugas tertentu. Menggunakan AWK bukan untuk menjadi lemah hati, lihat apa yang harus Anda lakukan untuk melakukan tugas dasar ini menggunakan AWK vs apa yang dibutuhkan solusi Glenn. Saya pikir saya bersikap adil dalam mengatakan bahwa itu adalah solusi yang lebih sederhana untuk dipahami secara mental, meskipun milik Anda mungkin lebih efisien. BTW, saya melakukan UV karena keduanya benar!
slm
1
@ HaukeLaging - Ya, persis. Ketika Anda berkeliaran di situs, tanggung jawab kami sedikit berubah, IMO. Kami bertanggung jawab untuk membuat A'ers yang komprehensif dan melihat A'ers yang kami berikan sebagai momen pengajaran bagi OP dan setiap pengunjung di masa mendatang yang melihatnya, lagi-lagi IMO. Tetapi ini adalah pilihan pribadi jadi jika Anda hanya memiliki sedikit waktu luang maka memberikan nilai A dalam bentuk apa pun selalu dihargai.
slm
6

uniqtampaknya menjadi solusi yang lebih pintar. Cara awk:

awk '{ip_count[$0]++}; '\
'END {for (ip in ip_count) printf "%15s: %d\n",ip,ip_count[ip];}' file
Hauke ​​Laging
sumber
+1. Jika urutan output penting untuk OP, jawaban ini tidak memberikan jaminan: iterasi atas kunci array asosiatif tidak memiliki urutan bawaan.
glenn jackman
@glennjackman Tetapi menambahkan sortjawaban saya masih lebih cepat karena lebih sedikit barang yang harus disortir. ;-)
Hauke ​​Laging
Oh ya? OH YA?!? ;) input sudah diurutkan. Jawaban awk ini mengocok mereka, jadi masih banyak pekerjaan. Nyah! ;)
glenn jackman
0

firest sort file kemudian hitung dengan unic -c

sort filename | uniq -c

Aeyd Moeyd
sumber
1
File sudah diurutkan (menurut pengguna dalam pertanyaan), dan uniq -cakan berfungsi tetapi memberikan output pada format yang salah. Inilah sebabnya mengapa jawaban yang diterima tidak menggunakan sortdan malah memformat ulang keluaran uniq -c.
Kusalananda
Terima kasih @Aeyd. Saya sedang mencari perintah ini. Ini membantu
user11392987
0

Saya akan menggunakan python. Setiap batang linux saat ini telah menginstal python2.

Tambahkan setiap alamat ip ke dalam dict (array asosiatif) sebagai kunci = pasangan nilai yaitu {"12.34.56.78": 1, "87.76.43.21": 3}.

Anda 'memverifikasi' alamat ip sebagai kunci dan menambah nilainya dengan 1. Jika Anda menggunakan defaultdict ("ip"), jika kunci tidak ada, itu dibuat dengan nilai default 0. Jika kunci memang ada sudah, defaultdict tidak melakukan apa-apa. Nilai bertambah pada baris berikutnya.

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

file keluar:

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

Saya tahu Anda mencari solusi baris perintah, tetapi seperti yang Anda lihat, ini adalah tampilan yang diformat secara elegan yang hanya membutuhkan sekitar selusin baris. Python adalah alat yang sangat baik untuk administrasi.

Mike Childers
sumber