The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]




Версия для распечатки Пред. тема | След. тема
Новые ответы [ Отслеживать ]
Bash Скрипт обработка писем или текстовых файлов, !*! ILYA INDIGO, 14-Июл-10, 22:03  [смотреть все]
:) Здравствуйте :)

Помогите написаить скрипт, который бы перебирал все письма в указанной папке, и выводил на консоль определённую информацию о этих письмах, а именно:
1 Имя файла
2 все IP адреса, встречающиеся в заголовках Received: письма;
3 все доменные имена, встречающиеся в теле письма.

В формате:

"Имя файла1"

Доменные имена из тела:
"Доменное имя 1"
"Доменное имя 2"
...
"Доменное имя n"

IP адреса из заголовка в строках начинающимся словом Received:
"IP 1"
"IP 2"
...
"IP n"

"Имя файла 2"
,,,
и т.д. для всех файлов, находящихся в указанной директории (например ./mail)


Задача, как я представляю, состоит из следующих этапов:

1.1 Передор директории ./mail
1.2 Вывод имени файла на консоль
2.1 Обработка тела писем и получение из них URL-ей email-ов и доменов (Тела письем от заголовков отделено пустой строкой)
2.2 Преобразование доменых имён из ранее полученных URL-ей (отфильровать текст между / и /) (http://vasya.narod.ua/forum/index.php -> vasya.narod.ua)
2.3 Преобразование доменых имён из ранее полученных email-ов (отфильтровать слова, содержащие @ и оставить только, то что после @) (vasya@narod.ua -> narod.ua)
2.4 Вывод всех полученных и преобразованных доменов из тела письма на консоль
3.1 Обработка заголовка писеми и получение из строк, начинающихся на Received: доменных имён и IP-адресов. (Заголовк начинаеться от начала письма, и кончается первой пустой строкой)
3.2 Преобразование доменных имён в IP-адреса. (vasya.narod.ua -> 109.10.158.16)
3.3 Вывод всех полученных и преобразованных IP-адресов из заголовка в консоль
4   Повторять цикл, пока не переберуться все файлы в директории ./mail

Подозреваю что  пункты 2 и 3 можно выполнить не деля их на подпункты, но пока незнаю через что именно их делать sed или awk или ещё через что то.

Пока только справился с 1 и 4 пунктами:

#!/bin/bash
DIR="./mail"
find $DIR -type f | while read FILE_NAME;
    do
        echo -e "\n\t$FILE_NAME"
        echo -e "\tdomain names:"
        cat $FILE_NAME | while read LINE
            do
                echo "$LINE"
            done
        echo -e "\tIPs:"
    done

Для удобства архив с папкой и письмами можно скачать отсюда http://ILYA.pp.ua/m.7z

Надеюсь, если и не на полное решение, то на частичное, а так же направление в нужную сторону :))

  • Bash Скрипт обработка писем или текстовых файлов, !*! ILYA INDIGO, 22:41 , 14-Июл-10 (1)
    Received: (qmail 32088 invoked from network); 7 Jan 2003 09:29:25 -0000
    Received: from dev213.mailshell.com (HELO mailshell.com) (@71.129.195.163)
      by dev50.mailshell.com with SMTP; 7 Jan 2003 09:29:25 -0000
    Received: (qmail 23535 invoked by uid 99); 7 Jan 2003 09:29:25 -0000
    Received: (qmail 6505 invoked from network); 7 Jan 2003 09:29:24 -0000
    Received: from unknown (HELO qmail8.arcamax.com) (209.96.210.81)
      by www.mailshell.com with SMTP; 7 Jan 2003 09:29:24 -0000
    Received: (qmail 15185 invoked from network); 7 Jan 2003 09:29:30 -0000
    Received: from qmail8.arcamax.com (209.96.210.81)

    Хочу добавить, что в теле письма IP-адреса находяться в скобках и всегда в конце строки, и возможно что определять их и не нужно, но всё же хотелось бы знать как можно преобразовать домен в IP, например использую ping или что то подобное.

    Но иногда бывает что перед IP адрессом стоит символ @

    (@71.129.195.163)

    • Bash Скрипт обработка писем или текстовых файлов, !*! L0n3R4ng3r, 12:22 , 15-Июл-10 (2)
      > хотелось бы знать как можно преобразовать домен в IP, например использую ping или что то > подобное.

      dig +short domen.com a

      • Bash Скрипт обработка писем или текстовых файлов, !*! ILYA INDIGO, 15:41 , 15-Июл-10 (3)
        >> dig +short domen.com a

        Спасибо большое за ответ :)

        На данный момент у меня код:

        #!/bin/bash
        clear
        DIR="./mail"
        find $DIR -type f | while read FILE_NAME;
            do
                echo -e "\n$FILE_NAME"
                echo "domain names:"
                echo "IPs:"
                awk '/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+[\)\]]/ {print substr($NF,2,length($NF)-3)}' $FILE_NAME
            done

        Где вро де бы и решил, частично, вывод всез IP-адресов, но всё же это далеко не идеал.

        1 Я Используя NF, в качестве разпознователя поля с IP, предпологаю, что IP лежит всегда в конце строки. В большинстве случаев это так, но НЕ всегда.
        2 Я предпологаю, что IP заключён всегда в круглые скобки, и при показе последнюю закрывающую скобку (последний символ поля) отбрасываю. И это не всегда так :(, так как некоторые IP умудряются быть записанныуми и в таком вот виде ([127,0,0,1]) т.е. заключённые сразу в 2 пары скобок, хотя теоретичиски предпологая, что может и попасться вариант вообще без скобок.
        3 Так что нужен цикл вывода только IP адресов, читающих их от первой цифры до последний цифры, при условии, что эти цифры могут заключаться в круглые () скобки или квадратные скобки [] или в обоя сразу, а так же могут быть заключены в пробел и/или символ переноса строки \n  в различных вароиациях (томеж находиться в начале строки, в середине строки или в конце строки.) А так же зона обработки должна быть от начала файла, и останавливаться, при обнаружениии первой пустой строки, как я понял при обнаружении \n\n, а дальше break в цикле или что т о тому подобное.

        Помогите пожалуйста реализовать, хотя бы, эту задачу, можно да же и не на awk, и даже не на Boerne Shell вообще (например Perl, Python, C/C++) уже более суток НЕ спал и голова совсем НЕ соображает уже :(

        • Bash Скрипт обработка писем или текстовых файлов, !*! L0n3R4ng3r, 18:26 , 15-Июл-10 (4)
          >[оверквотинг удален]
          >символ переноса строки \n  в различных вароиациях (томеж находиться в
          >начале строки, в середине строки или в конце строки.) А так
          >же зона обработки должна быть от начала файла, и останавливаться, при
          >обнаружениии первой пустой строки, как я понял при обнаружении \n\n, а
          >дальше break в цикле или что т о тому подобное.
          >
          >Помогите пожалуйста реализовать, хотя бы, эту задачу, можно да же и не
          >на awk, и даже не на Boerne Shell вообще (например Perl,
          >Python, C/C++) уже более суток НЕ спал и голова совсем НЕ
          >соображает уже :(

          я бы посоветовал использовать perl все таки он изобретен для обработки текста и как никто лучше справляеться с єтой задачей


          для айпишников цикл будет выглядеть примерно так :


          use Socket;

          my $file = 'path/to/file';
          my @ips;
          open(FILE,"<$file");
          while(<FILE>){
          if ( /(\d+\.\d+\.\d+\.\d+)/  ){
             my $ip = $1;
             @ips = push(@ips,$ip); #для того чтобы поместить айпишник в масив ips(если нужно)
             print "$ip\n"; # для того чтобы вывести его
             $ip = inet_aton($ip);
             $name  = gethostbyaddr($ip, AF_INET); # для того чтобы вернуть его доменое имя
          }
          }


          ну вот где-то так.. печатал сразу тут так что на ерроры не проверял.

          • Bash Скрипт обработка писем или текстовых файлов, !*! McLeod095, 17:00 , 16-Июл-10 (5)
            >[оверквотинг удален]
            >   print "$ip\n"; # для того чтобы вывести его
            >   $ip = inet_aton($ip);
            >   $name  = gethostbyaddr($ip, AF_INET); # для того чтобы
            >вернуть его доменое имя
            > }
            >}
            >
            >
            >ну вот где-то так.. печатал сразу тут так что на ерроры не
            >проверял.

            лучше наверное используйте все таки перл. Он точно со всем справится, и будет довольно удобно.
            Ну и почитайте книжку по регулярным выражениям.
            Вот регулярное выражение для поиска IP адреса который приведен в этой книге
            ^([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])$


            • Bash Скрипт обработка писем или текстовых файлов, !*! L0n3R4ng3r, 18:11 , 16-Июл-10 (6)
              >[оверквотинг удален]
              >>
              >>ну вот где-то так.. печатал сразу тут так что на ерроры не
              >>проверял.
              >
              >лучше наверное используйте все таки перл. Он точно со всем справится, и
              >будет довольно удобно.
              >Ну и почитайте книжку по регулярным выражениям.
              >Вот регулярное выражение для поиска IP адреса который приведен в этой книге
              >
              >^([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])$

              Спасибо за заботу по-поводу книжки по регекспам, но должен вас разочеровать даный регексп не рабочий. Визуально он вроди бы составлен правильно, но на практите это не так:
              $ echo '1' | perl -ne '/([01]?\d\d?|2[0-4]\d|25[0-5])/; print "$1\n"'
              1
              $ echo '10' | perl -ne '/([01]?\d\d?|2[0-4]\d|25[0-5])/; print "$1\n"'
              10
              $ echo '110' | perl -ne '/([01]?\d\d?|2[0-4]\d|25[0-5])/; print "$1\n"'
              110
              $ echo '232' | perl -ne '/([01]?\d\d?|2[0-4]\d|25[0-5])/; print "$1\n"'
              23
              $ echo '255' | perl -ne '/([01]?\d\d?|2[0-4]\d|25[0-5])/; print "$1\n"'
              25

              Тоесть октеты начинающиеся на 2хх тупо режуться до двух первых символов. И вообще использовать его в коде не очень хорошая идея если вы еще хотите использовать этот код :)

              Проще использовать такой регексп - /(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/ . У него есть минимальное количество проверок на валидность, правда намного меньше чем в вашем, но такие проверки на 99.9% бесполезны.

            • Bash Скрипт обработка писем или текстовых файлов, !*! ILYA INDIGO, 15:10 , 17-Июл-10 (8)
              >Вот регулярное выражение для поиска IP адреса который приведен в этой книге
              >
              >^([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])$

              При таком алгоритме вывод вообще пустой, а если убрать ^ в начале и $, то аналогичен вы воду Второго алгоритма т.е.

              71
              63
              10

          • Bash Скрипт обработка писем или текстовых файлов, !*! ILYA INDIGO, 14:58 , 17-Июл-10 (7)
            >я бы посоветовал использовать perl все таки он изобретен для обработки текста
            >и как никто лучше справляеться с єтой задачей
            >
            >ну вот где-то так.. печатал сразу тут так что на ерроры не
            >проверял.

            Ок спасибо за совет и ответ, я таки, буду пытаться это переделать на PERL-е.

            Но алгоритм всё равно не работает должным образом...

            Вот фрагмент текста письма, находящегося в файле: ./mail/111

            Received: (qmail 29944 invoked from network); 8 Jan 2003 07:10:33 -0000
            Received: from dev212.mailshell.com (HELO mailshell.com) (71.129.195.163)
              by dev50.mailshell.com with SMTP; 8 Jan 2003 07:10:33 -0000
            Received: (qmail 26211 invoked by uid 99); 8 Jan 2003 07:10:33 -0000
            Message-ID: <20030108071033.15907.qmail@mailshell.com>
            Received: (qmail 13669 invoked from network); 8 Jan 2003 07:10:31 -0000
            Received: from unknown (HELO anclsmtp03.myfamily.com) (63.92.90.192)
              by www.mailshell.com with SMTP; 8 Jan 2003 07:10:31 -0000
            Received: from ancnews01 (10.6.8.151) by anclsmtp03.myfamily.com (LSMTP for Windows NT v1.1b) with SMTP id <22.00312C4E@anclsmtp03.myfamily.com>; Wed, 8 Jan 2003 0:11:17 -0700
            X-Sender: <unsubscribe.nbrc8744.000001.1048576.0.0@unsubscribe.myfamily.com>
            Reply-To: <unsubscribe.nbrc8744.000001.1048576.0.0@unsubscribe.myfamily.com>
            From: "Ancestry Special Offer" <newsletter@Reply.MyFamilyInc.com>
            To: "Mailshell User" <nospam@mailshell.com>
            Subject: Connect with your ancestors online
            Date: Wed, 08 Jan 2003 07:11:15 -0000

            Connect with your ancestors online. Join Ancestry.com
            ...
            Всё ниже со слова Connect является заголовком, или по крайней мере, не нуждается в обработки по IP.

            Вот ваш предложенный код:

            #!/usr/bin/perl
            use Socket;

            my $file = './mail/111';
            my @ips;
            open(FILE,"<$file");
            while(<FILE>){
            if ( /(\d+\.\d+\.\d+\.\d+)/  ){ # Первый алгоритм
            # if ( /(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/  ){ # Второй алгоритм
               my $ip = $1;
               @ips = push(@ips,$ip); #для того чтобы поместить айпишник в масив ips(если нужно)
               print "$ip\n"; # для того чтобы вывести его
               $ip = inet_aton($ip);
               $name  = gethostbyaddr($ip, AF_INET); # для того чтобы вернуть его доменое имя
            }
            }perl

            При первом алгоритме имеем такой вывод:

            71.129.195.163
            63.92.90.192
            10.6.8.151
            8744.000001.1048576.0
            8744.000001.1048576.0

            При втором алгоритме имеем следующий вывод:

            71
            63
            10

            Вот из-за наличия таких "противных" строк как

            Reply-To: <unsubscribe.nbrc8744.000001.1048576.0.0@unsubscribe.myfamily.com>

            Первый алгоритм не до конца эффективен, так как нужно строго указать, что цифр может быть НЕ менее 1, но и не более 3.

            Второй алгоритм, почему-то, выделяет прочто первую циру каждого IP-шника, хотя отфильтровует IP верно.

            >Ну и почитайте книжку по регулярным выражениям.

            Подскажите пожалуйста сею книжку, а лучше и url на неё. Я составлял алгоритм, основываясь на этом http://www.opennet.me/docs/RUS/bash_scripting_guide/c11895.h...

            P.S. Чувствую тему уже нужно переносить в раздел PERL, но если кто то уверен, что с текущей задачей можно справиться средствами Bash, пожалуйста, предлогайте свои решения :)

            Напоминаю папку с письмами,что бы проверить как скрипт должен работать в реальных условиях, можно скачать тут http://ILYA.pp.ua/m.7z

            • Bash Скрипт обработка писем или текстовых файлов, !*! L0n3R4ng3r, 01:29 , 18-Июл-10 (9)
              используйте регексп (\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3}) для определения айпишников:

              вот файл с письмом :
              $ cat qwe
              Received: (qmail 29944 invoked from network); 8 Jan 2003 07:10:33 -0000
              Received: from dev212.mailshell.com (HELO mailshell.com) (71.129.195.163)
                by dev50.mailshell.com with SMTP; 8 Jan 2003 07:10:33 -0000
              Received: (qmail 26211 invoked by uid 99); 8 Jan 2003 07:10:33 -0000
              Message-ID: <20030108071033.15907.qmail@mailshell.com>
              Received: (qmail 13669 invoked from network); 8 Jan 2003 07:10:31 -0000
              Received: from unknown (HELO anclsmtp03.myfamily.com) (63.92.90.192)
                by www.mailshell.com with SMTP; 8 Jan 2003 07:10:31 -0000
              Received: from ancnews01 (10.6.8.151) by anclsmtp03.myfamily.com (LSMTP for Windows NT v1.1b) with SMTP id <22.00312C4E@anclsmtp03.myfamily.com>; Wed, 8 Jan 2003 0:11:17 -0700
              X-Sender: <unsubscribe.nbrc8744.000001.1048576.0.0@unsubscribe.myfamily.com>
              Reply-To: <unsubscribe.nbrc8744.000001.1048576.0.0@unsubscribe.myfamily.com>
              From: "Ancestry Special Offer" <newsletter@Reply.MyFamilyInc.com>
              To: "Mailshell User" <nospam@mailshell.com>
              Subject: Connect with your ancestors online
              Date: Wed, 08 Jan 2003 07:11:15 -0000

              Connect with your ancestors online. Join Ancestry.com

              вот вывод:
              $ cat qwe  | perl -ne 'if (/(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/) { print "$1.$2.$3.$4\n" }'
              71.129.195.163
              63.92.90.192
              10.6.8.151




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру