Подсчет количества раз каждый 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-адреса в порядке и непосредственно друг за другом.

Джеймс Спиттал
источник
Лично я импортировал бы этот тип файла в удобную близлежащую БД (создав временную таблицу в любом имеющемся у меня экземпляре postgres) с последующим быстрым действием 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, ОП утверждает, что он уже отсортировал результаты, используя sort!
SLM
2
@HaukeLaging - я ценю то, что вы говорите, но точно так же, как большинство пользователей компьютеров никогда не выйдут за пределы OSX и Windows, тем не менее, большинство пользователей Unix не будут рисковать, используя специально предназначенные для этих задач инструменты. Использование AWK не для слабонервных, посмотрите, что вам нужно было сделать для выполнения этой основной задачи с использованием AWK, в отличие от того, что требовалось для решения Гленна. Я думаю, что я честен, говоря, что это более простое решение для умственного понимания, хотя ваше, вероятно, более эффективно. Кстати, я сделал UV оба, так как они оба правильные!
SLM
1
@HaukeLaging - Да, именно так. По мере того, как ты слоняешься по сайту, наши обязанности немного меняются, ИМО Мы несем ответственность за создание всесторонних A'ers и рассматриваем A'ers, которые мы предоставляем в качестве обучающих моментов для OP и каждого будущего посетителя, который сталкивается с ним, снова IMO. Но это личный выбор, поэтому, если у вас есть всего несколько минут, то всегда приветствуется предоставление А в любой форме.
SLM
6

uniqкажется, действительно, более умное решение. Путь awk:

awk '{ip_count[$0]++}; '\
'END {for (ip in ip_count) printf "%15s: %d\n",ip,ip_count[ip];}' file
Хауке Лагинг
источник
+1. Если порядок вывода важен для OP, этот ответ не дает никаких гарантий: перебор ключей ассоциативного массива не имеет собственного порядка.
Гленн Джекман
@glennjackman Но добавление sortв мой ответ все еще происходит быстрее, так как нужно сортировать меньше элементов. ;-)
Хауке Лагинг
о, да? О, ДА?!? ;) вход уже отсортирован. Этот ответ на awk тасует их, так что это еще больше работы. Nyah! ;)
Гленн Джекман
0

самый сильный файл сортировки, затем получить счетчик по unic -c

sort filename | uniq -c

Эйд Мойд
источник
1
Файл уже отсортирован (в соответствии с пользователем в вопросе), и uniq -cбудет работать, но вывести результат в неправильном формате. Вот почему принятый ответ не использует, sortа вместо этого переформатирует вывод uniq -c.
Кусалананда
Спасибо @Aeyd. Я искал эту команду. Помогает
user11392987
0

Я бы использовал Python. На каждом Linux-ststem в настоящее время установлен python2.

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

Вы 'проверяете' IP-адрес в качестве ключа и увеличиваете значение на 1. Если вы используете defaultdict ("ip"), если ключ не существует, он создается со значением по умолчанию, равным 0. Если ключ существует уже defaultdict ничего не делает. Значение увеличивается на следующей строке.

#!/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 - отличный инструмент для администрирования.

Майк Чилдерс
источник