LinuxForum.Fans
Тема

Вывод строки которая повторяется более n раз.

Автор: Rassol2 19 сообщений 4469 просмотров
#270361

Здравствуйте.
Интересует вопрос какая утилита может вывести строки которые повторяются в файле более 1000 раз
спросил бы у гугла но не знаю как сформулировать правильно вопрос.

А если по длиннее то получается я имею файл в котором записаны сотни ип, и мне нужно отобрать только параноидально активных, которые записаны более 1к рас.
Ипы записаны в столбик.
Это файл с дампа tcp трафика. приведен он к виду

Показать
207.10.162.52.3962
207.10.162.52.3962
207.10.162.52.3961
207.10.162.52.3961
207.10.162.52.3988
207.10.162.52.3988
207.10.162.52.3961
207.10.162.52.3988
207.10.162.52.3989
207.10.162.52.3989
207.10.162.52.3989
207.10.162.52.3782
adsl-99-136-111-230.dsl.lsan03.sbcglobal.net.49845
adsl-99-136-111-230.dsl.lsan03.sbcglobal.net.49844
207.10.162.52.3788
207.10.162.52.4021
207.10.162.52.3790
207.10.162.52.3792
207.10.162.52.3791
207.10.162.52.4020
bementil-90.illinois.sparkplugbb.net.4747
207.10.162.52.3965
bementil-90.illinois.sparkplugbb.net.4740
207.10.162.52.3965
207.10.162.52.3965
207.10.162.52.3991
207.10.162.52.3992
207.10.162.52.3991
207.10.162.52.3991
207.10.162.52.3992
207.10.162.52.3992
207.10.162.52.3793
207.10.162.52.3995
207.10.162.52.3995

Для того что бы почистить лишнее использовал sed , ну и grep - с этими утилитами знаком очень поверхностно и возможно они это умеет.
Подскажите плиз.

#270363

Попробуйте, в качестве аргумента должен передаваться файл со списком адресов.

text
#!/bin/bash
LIST_IP="${1}"
NUM=100 
for i in $(sort -u "${LIST_IP}");
do              
                [[ $(grep -c "${i}" "${LIST_IP}")  > ${NUM} ]] && echo "${i}"
done
#270364
text

#!/usr/bin/env python
#-*- coding: utf-8 -*-
import sys
dictionary = {}
for line in open(sys.argv[1]).readlines(): 
    if line in dictionary:
        dictionary[line] +=1
    else: 
        dictionary[line] = 1
for key in dictionary:
    if dictionary[key] >= 1000:
        print key.strip()

Файл передаётся в качестве параметра скрипту.

#270371

Lupo Alberto, -=Serj=-
Протестил ваши скрипты на логе с 150000 строками.
Результат конечно разный а вот кому верить )

Правда лог оказался чучуть другой, там не только ип но и под домены провайдеров были. короче вот такой в этот рас.

Показать
60.170.189.89.sta.211.ru.50177
60.170.189.89.sta.211.ru.50179
60.170.189.89.sta.211.ru.50181
60.170.189.89.sta.211.ru.50183
60.170.189.89.sta.211.ru.50185
68.64.47.244.www
69.58.188.39.www
69.58.188.40.www
70-182-113-92.pool.ukrtel.net.1106
77.123.107.220.1180
77.123.55.141.3190
78-137-9-107.dynamic-pool.mclaut.net.3034
78-137-9-107.dynamic-pool.mclaut.net.3043
78-25-54-252.static.vega-ua.net.1170
8-119-135-95.pool.ukrtel.net.26888
82.193.99.71.usernat.ip.net.ua.58312
84.53.214.90.1949
85.115.248.47.37921
88.135.229.230.2557
88.237.broadband6.iol.cz.22249
88.237.broadband6.iol.cz.22250
91.192.182.6.2362

Lupo Alberto, у вас я поправил еше строку NUM=100 на NUM=1000
результат вышел в 2067 ип. здесь выкладывать не буду :)

-=Serj=- А вот ваш дал вот такой результат. его и выложить несложно.

Показать
dynamicip-46-147-222-70.pppoe.chel.ertelecom.ru.64104
84.53.214.90.1949
dnm.91.3.185.178.dsl.krasnet.ru.50818
151.0.30.217.1187
dhcp-13-230-208-178.metronv.ru.50026
244-240-112-92.pool.ukrtel.net.49714
85.115.248.47.37921
78-137-9-107.dynamic-pool.mclaut.net.3043
46.98.134.170.3791
88.237.broadband6.iol.cz.22249
88.135.229.230.2557
shpd-92-101-162-156.vologda.ru.3430
46.109.235.33.54695
ppp-141-101-0-164.wildpark.net.2500
91.205.216.39.51261
31.131.78.144.49299
#270372
"Rassol2" написал:
Протестил ваши скрипты на логе с 150000 строками.
Результат конечно разный а вот кому верить )

Попробуйте сначала

text

sort -u list.txt | wc -l

чтобы получить количество уникальных адресов и соотнести его с результатами работы скриптов.

"Rassol2" написал:
Lupo Alberto, у вас я поправил еше строку NUM=100 на NUM=1000

Это только пример.
Если не сложно, дайте полный файл с адресами, ну или хотя бы кусок по-больше, в пару тысяч строк.

#270373

Rassol2, для проверки моего, замените последнюю строчку на

text
print "%s --- %d" % (key.strip(), dictionary[key])

так будет выводиться количество повторений. Уменьшите кол-во искомых повторений, например до 3х и подсуньте ему небольшой файл, где вы сможете проверить кол-во совпадений...
Ну и для более точного сравнения скриптов, измените в

text
if dictionary[key] >= 1000:

>= на >.

#270482

Чуть пожже проведем опыты.

#270562
"Rassol2" написал:
Интересует вопрос какая утилита может вывести строки которые повторяются в файле более 1000 раз

яхз. Могу скрипт набросать:

text
#!/bin/bash

declare -A dic declare -a strs WORD_COUNT=0

while read s; do COUNT=${dic["$s"]} (( COUNT++ )) #echo $s $COUNT dic["$s"]=$COUNT if [ $COUNT == 1 ]; then # первое вхождение strs[$WORD_COUNT]=$s (( WORD_COUNT++ )) fi done < ~/tmp/test.txt

echo "-----"

TMP1=`mktemp`

for (( i = 0; i < $WORD_COUNT; i++ )); do s=${strs[$i]} echo ${dic["$s"]} "'$s'" >> $TMP1 done

sort -rn $TMP1 | head -n15

rm --force $TMP1

Идея в том, что используются ассоциативный массив bash'а, в котором сохраняется число повторений. Далее этот массив сортируется, и выводятся первые 15 строчек.
Вот так:

text
$ ./uniq1000.bash 
-----
3 '207.10.162.52.3992'
3 '207.10.162.52.3991'
3 '207.10.162.52.3989'
3 '207.10.162.52.3988'
3 '207.10.162.52.3965'
3 '207.10.162.52.3961'
2 '207.10.162.52.3995'
2 '207.10.162.52.3962'
1 'bementil-90.illinois.sparkplugbb.net.4747'
1 'bementil-90.illinois.sparkplugbb.net.4740'
1 'adsl-99-136-111-230.dsl.lsan03.sbcglobal.net.49845'
1 'adsl-99-136-111-230.dsl.lsan03.sbcglobal.net.49844'
1 '207.10.162.52.4021'
1 '207.10.162.52.4020'
1 '207.10.162.52.3793'
#270566
"-=Serj=-" написал:
#!/usr/bin/env python

есть 2 недостатка у этого скрипта:
1. Я сомневаюсь, что ТС знает пайтон, и что ему это нужно сейчас. Очевидно он просил решение на bash, ибо непонятно, есть-ли у него вообще пайтон, и если есть, то какой версии?
2. Заранее сложно узнать, сколько в файле повторяющихся строк. Не проще-ли вывести самые частые?

#270567
"drBatty" написал:
выводятся первые 15 строчек.

Так, вроде, нужно все, которые повторяются более 1000 раз. А твой, как я понял, выдаст 15 самых повторяющихся...

#270568

"Lupo Alberto" написал:
#!/bin/bash LIST_IP="${1}" NUM=100 for i in $(sort -u "${LIST_IP}"); do [[ $(grep -c "${i}" "${LIST_IP}") > ${NUM} ]] && echo "${i}" done
если честно, не распарсил. Лихо закручено...
#270569
"drBatty" написал:
если честно, не распарсил.

«Не верю!» ©Станиславский
;)

#270570
"drBatty" написал:
1. Я сомневаюсь, что ТС знает пайтон, и что ему это нужно сейчас.

Не, ну на чём умею, на том и нацарапал

"drBatty" написал:
если есть, то какой версии?

Пока-что вторая версия у всех по-умолчанию... Вроде...

#270571
"-=Serj=-" написал:
Так, вроде, нужно все, которые повторяются более 1000 раз. А твой, как я понял, выдаст 15 самых повторяющихся...

а ТС сам не знает, чего ему надо ;)

"Rassol2" написал:
А если по длиннее то получается я имею файл в котором записаны сотни ип, и мне нужно отобрать только параноидально активных, которые записаны более 1к

Согласитесь, что 1К тут взято чисто от балды.
В предъявленном тестовом файле очевидно таких записей нет, потому тестирование возможно только у ТСа, и ни у кого другого...

#270575
"Lupo Alberto" написал:
«Не верю!»

а зря, ибо действительно не распарсил. Лениво просто. Лично я ТАКОГО не пишу, ибо потом сам замучаюсь разбираться...

"-=Serj=-" написал:
Пока-что вторая версия у всех по-умолчанию... Вроде...

ORLY?

The current production versions are Python 2.7.3 and Python 3.2.3.
Start with one of these versions for learning Python or if you want the most stability; they're both considered stable production releases.
If you don't know which version to use, start with Python 2.7; more existing third party software is compatible with Python 2 than Python 3 right now.

http://www.python.org/download/
в гробу я видел ЯП, у которых ДВЕ текущие несовместимые версии...

#270621

drBatty
о какие люди в галивуде.

Ну 15 самых активных не подойдет. К примеру если сыпется дос с 100 ипов и дамп за 10сек составляет 300000 строк. То я не получу большого ефекта если начну отсекать 15 ип всего.
Ведь нужно найти тех кто умудрился за 10 сикунд прислать около 1000 или 2000 тысяч запросов.

#270634
"Rassol2" написал:
Ну 15 самых активных не подойдет.

вот проблема-то!

text
while read COUT STRING; do
    if (( COUNT < 1000 )); then
        break
    fi
done

этот цикл напечатает все строчки в порядке убывания до 1000 повторов включительно.

"Rassol2" написал:
Ведь нужно найти тех кто умудрился за 10 сикунд прислать около 1000 или 2000 тысяч запросов.

это тоже можно реализовать, хотя и сложнее. Для этого уже есть смысл подключить СУБД, ибо это уже достаточно сложная, и ресурсоёмкая операция. Кстати, сам лог можно сохранять не только в текстовом файле, а отправлять напрямую в СУБД, это получается намного быстрее, если нужны такие сложные действия.

#271183

Кстати, сам лог можно сохранять не только в текстовом файле, а отправлять напрямую в СУБД, это получается намного быстрее, если нужны такие сложные действия.

Всему свое время. Пока что я осваиваю это. Причем дается довольно сложно. Тупой я короче :)

#271226
"Rassol2" написал:
Всему свое время. Пока что я осваиваю это. Причем дается довольно сложно. Тупой я короче

мне это тоже непросто даётся на самом деле...

Войдите или зарегистрируйтесь, чтобы ответить.