Đếm số lần mỗi địa chỉ IP xuất hiện trong tệp nhật ký


9

Tôi có một tập tin theo định dạng như sau:

$ 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

Cách tốt nhất để phân tích tệp file.txtthành một định dạng như:

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

Nói cách khác, tôi muốn lặp qua tệp và đếm số lần mỗi địa chỉ IP xuất hiện. Tôi đã chạy nó qua sortđể tất cả các địa chỉ IP được xếp theo thứ tự và trực tiếp lẫn nhau.


Cá nhân tôi sẽ nhập loại tệp này vào một DB tiện dụng gần đó (bằng cách tạo bảng tạm thời trong bất kỳ trường hợp postgres nào tôi có), theo sau là một hành động SQL nhanh và xuất trở lại tệp văn bản.
Oakad

Câu trả lời:


23

Bạn đang tìm uniq -c

Nếu đầu ra của nó không theo ý thích của bạn, nó có thể được phân tích cú pháp và định dạng lại dễ dàng.

Ví dụ:

$ 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

Kết hợp uniqawkdường như không phải là một cách tiếp cận tuyệt vời với tôi ...
Hauke ​​Laging

3
Bởi vì uniqchỉ hoạt động trên đầu vào được sắp xếp (nó khớp với các dòng khớp liền kề, không phải bất kỳ dòng nào từ tệp).
Oakad

1
Bạn phải sắp xếp các kết quả trước khi đặt chúng vào uniq. Nếu bạn đọc Q ban đầu, OP tuyên bố rằng anh ấy đã sắp xếp kết quả bằng cách sử dụng sort!
slm

2
@HaukeLaging - Tôi đánh giá cao những gì bạn nói nhưng cũng giống như hầu hết người dùng máy tính sẽ không bao giờ mạo hiểm ngoài OSX & Windows, hơn nữa hầu hết người dùng Unix sẽ không mạo hiểm sử dụng các công cụ được chỉ định cho các tác vụ cụ thể. Sử dụng AWK không dành cho người yếu tim, hãy nhìn vào những gì bạn phải làm để thực hiện nhiệm vụ cơ bản này bằng AWK so với những gì giải pháp của Glenn yêu cầu. Tôi nghĩ rằng tôi công bằng khi nói rằng anh ấy là một giải pháp đơn giản hơn để nắm bắt về mặt tinh thần, mặc dù khả năng của bạn có hiệu quả hơn. BTW, tôi đã làm cả UV vì cả hai đều đúng!
slm

1
@HaukeLaging - Vâng, chính xác. Khi bạn đi quanh trang web, trách nhiệm của chúng tôi thay đổi một chút, IMO. Chúng tôi chịu trách nhiệm tạo ra những Người toàn diện và nhìn vào những Người mà chúng tôi cung cấp như những khoảnh khắc giảng dạy cho OP và mọi khách truy cập trong tương lai đi qua nó, một lần nữa IMO. Nhưng đó là một lựa chọn cá nhân vì vậy nếu bạn chỉ có vài phút rảnh rỗi thì việc cung cấp A dưới mọi hình thức luôn được đánh giá cao.
slm

6

uniqdường như là giải pháp thông minh hơn, thực sự. Cách thức tuyệt vời:

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

+1. Nếu thứ tự đầu ra là quan trọng đối với OP, câu trả lời này không đảm bảo: lặp lại các khóa của một mảng kết hợp không phải là thứ tự vốn có.
glenn jackman

@glennjackman Nhưng thêm sortvào câu trả lời của tôi vẫn nhanh hơn vì phải sắp xếp ít mục hơn. ;-)
Hauke ​​Laging

oh vâng? OH YEAH?!? ;) đầu vào đã được sắp xếp. Câu trả lời awk này xáo trộn họ, vì vậy nó vẫn còn nhiều việc hơn. Ơ! ;)
glenn jackman

0

tập tin sắp xếp linh hoạt nhất sau đó được tính bởi unic -c

sort filename | uniq -c


1
Tệp đã được sắp xếp (theo người dùng trong câu hỏi) và uniq -csẽ hoạt động nhưng cung cấp đầu ra ở định dạng sai. Đây là lý do tại sao câu trả lời được chấp nhận không sử dụng sortvà thay vào đó định dạng lại đầu ra của uniq -c.
Kusalananda

Cảm ơn @Aeyd. Tôi đã tìm kiếm lệnh này. Nó giúp
user11392987 18/11/19

0

Tôi sẽ sử dụng trăn. Mọi ststem linux hiện nay đều đã cài đặt python2.

Thêm từng địa chỉ IP vào một dict (mảng kết hợp) dưới dạng cặp key = value tức là {"12.34.56.78": 1, "87.76.43.21": 3}.

Bạn 'xác minh' địa chỉ IP làm khóa và tăng giá trị lên 1. Nếu bạn sử dụng defaultdict ("ip"), nếu khóa không tồn tại, nó được tạo với giá trị mặc định là 0. Nếu khóa tồn tại đã, defaultdict không làm gì cả. Giá trị được tăng lên trên dòng tiếp theo.

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

tập tin ra:

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

Tôi biết bạn đang tìm kiếm một giải pháp dòng lệnh, nhưng như bạn có thể thấy đó là một màn hình được định dạng thanh lịch chỉ mất hàng tá dòng. Python là một công cụ tuyệt vời để quản trị.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.