Підрахунок кількості разів, коли кожна IP-адреса з’являється у файлі журналу


9

У мене є файл у такому форматі:

$ 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

Який найкращий спосіб розібрати файл file.txtу такий формат:

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

Іншими словами, я хочу переглядати файл і рахувати кількість разів, коли кожна IP-адреса з’являється. Я вже запустив це, sortщоб усі IP-адреси були в порядку та безпосередньо один за одним.


Я особисто імпортував такий файл у зручну сусідню БД (створивши таблицю тимчасових тем у будь-якому екземплярі постгресів), з подальшим швидким дією SQL та експортом назад у текстовий файл.
оакад

Відповіді:


23

Ви шукаєте uniq -c

Якщо результат цього не сподобався, його можна легко проаналізувати та переформатувати.

Наприклад:

$ 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

Поєднання uniqі awk, здається, не є великим підходом до мене ...
Хоуке Лагінг

3
Тому що uniqпрацює лише на впорядкованому вході (він відповідає суміжним рядкам, що відповідають, а не будь-яким рядкам з файлу).
оакад

1
Ви повинні відсортувати результати перед тим, як передати їх у uniq. Якщо ви читаєте оригінал Q, OP заявляє, що він вже сортував результати, використовуючи sort!
slm

2
@HaukeLaging - Я ціную те, що ви говорите, але так само, як і більшість користувачів комп'ютерів ніколи не виходитимуть за межі OSX та Windows, далі все-таки більшість користувачів Unix не будуть ризикувати за допомогою призначених інструментів для конкретних завдань. Використання AWK не для слабкого серця, подивіться, що вам довелося виконати для виконання цієї основної задачі, використовуючи AWK проти того, що потрібно для рішення Глена. Я думаю, що я чесно кажу, що його більш просте рішення подумки зрозуміти, хоча ваш, швидше за все, більш ефективний. До речі, я зробив УФО обидва, оскільки вони обидва правильні!
slm

1
@HaukeLaging - Так, саме так. Коли ви зависаєте над сайтом, наші обов'язки незначно змінюються, IMO. Ми несемо відповідальність за створення всеохоплюючих «Е-ерів» і дивимось на «Еер», який ми пропонуємо, як навчальні моменти для ОП та кожного майбутнього відвідувача, який натрапив на нього, знову ж таки ІМО. Але це особистий вибір, тому якщо у вас є лише кілька хвилин для запасного, то надання А в будь-якій формі завжди цінується.
slm

6

uniqздається, розумнішим рішенням є насправді. Будний спосіб:

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

+1. Якщо порядок виводу важливий для ОП, ця відповідь не дає жодних гарантій: ітерація над ключами асоціативного масиву не має властивого порядку.
glenn jackman

@glennjackman Але додавання sortдо моєї відповіді все ще швидше, оскільки потрібно сортувати менше елементів. ;-)
Hauke ​​Laging

о так? О ТАК?!? ;) вхід вже відсортований. Ця відповідь у відповідь переміщує їх, тому це ще більше роботи. Nyah! ;)
Глен Джекман

0

файл сортування firest, тоді підраховуйте unic -c

sort filename | uniq -c


1
Файл вже відсортований (за даними користувача у запитанні), і uniq -cвін працює, але забезпечує вихід у неправильному форматі. Ось чому прийнята відповідь не використовує, sortа замість цього переформатує результат uniq -c.
Kusalananda

Дякую @Aeyd Я шукав цю команду. Це допомагає
user11392987

0

Я б використав python. У кожному linux ststem на сьогодні встановлено python2.

Додайте кожну ip адресу в дикт (асоціативний масив) як ключ = пари значень, тобто {"12.34.56.78": 1, "87.76.43.21": 3}.

Ви 'перевіряєте' ip-адресу як ключ і збільшуєте значення на 1. Якщо ви використовуєте defaultdict ("ip"), якщо ключ не існує, він створюється зі значенням за замовчуванням 0. Якщо ключ існує вже, дефолт не робить нічого. Значення збільшується в наступному рядку.

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

вихідний файл:

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

Я знаю, що ви шукали рішення командного рядка, але, як ви бачите, це елегантно відформатований дисплей, який займав лише десяток рядків або близько того. Python - відмінний інструмент для адміністрування.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.