2015-12-29 3 views
0

Мне нужно выполнить поиск whois в файле, содержащем IP-адреса, и вывести как код страны, так и IP-адрес в новый файл. В моей команде до сих пор я нахожу IP-адреса и получаю уникальную копию, которая не соответствует допустимым диапазонам. Затем я запускаю поиск whois, чтобы узнать, кто такие иностранные адреса. Наконец, он вытаскивает код страны. Это отлично работает, но я не могу заставить его показать мне IP вместе с кодом страны, поскольку он не включен в выход whois.Выравнивание результатов конвейера вместе с вводом (здесь, «ip» и результаты whois grep)

Что было бы лучшим способом включить IP-адрес в выходной файл?

awk '{match($0,/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/); ip = substr($0,RSTART,RLENGTH); print ip}' myInputFile \ 
    | sort \ 
    | uniq \ 
    | grep -v '66.33\|66.128\|75.102\|216.106\|66.6' \ 
    | awk -F: '{ print "whois " $1 }' \ 
    | bash \ 
    | grep 'country:' \ 
    >> myOutputFile 

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

Ниже приведен пример ввода:

27 4:03:30 smtpfive декабрю Sendmail [14851]: tBRA3HAx014842: с =, задержка = 00: 00: 12, xdelay = 00: 00: 01, mailer = esmtp, pri = 1681345, relay = redcondor.itctel.c om. [75.102.160.236], dsn = 4.3.0, stat = Отложенное: 451 Превышен предел для этого пользователя nder 27 дек. 04:03:30 smtpfive sendmail [14851]: tBRA3HAx014842: to =, delay = 00: 00: 12, xdelay = 00: 00: 01, mailer = esmtp, pri = 1681345, relay = redcondor.itctel.c om. [75.102.160.236], DSN = 4,3,0, стат = Отложено: 451 предел получателя превышена для этого се NDER

Спасибо.

+3

'awk | сортировать | uniq | grep | awk | Баш | grep' звучит немного чрезмерно. Возможно, вы можете предоставить образец 'myInputFile' вместе с желаемым результатом, чтобы мы могли предложить лучший подход. – fedorqui

+0

FYI, более эффективно помещать '> any' после' done', а не повторно открывать файл каждый раз, когда вы хотите запустить команду 'whois'. –

+0

Кроме того, я полностью согласен с @fedorqui - я не могу придумать обстоятельства, при которых ваш трубопровод не может быть сбит до двух элементов и не более.(Имейте в виду, что 'awk' может выполнять сортировку и uniq'ing, а grepping - инвертировать или иначе) –

ответ

2

В целом: Итерируйте по своим входам в качестве переменных оболочки; это затем позволяет печатать их вместе с каждым выходом из оболочки.


нижеописанных будет работать с Баш 4.0 или более поздней версии (требуется ассоциативные массивы):

#!/bin/bash 
#  ^^^^- must not be /bin/sh, since this uses bash-only features 

# read things that look vaguely like IP addresses into associative array keys 
declare -A addrs=() 
while IFS= read -r ip; do 
    case $ip in 66.33.*|66.128.*|75.102.*|216.106.*|66.6.*) continue;; esac 
    addrs[$ip]=1 
done < <(grep -E -o '[0-9]+[.][0-9]+[.][0-9]+[.][0-9]+') 

# getting country code from whois for each, printing after the ip itself 
for ip in "${!addrs[@]}"; do 
    country_line=$(whois "$ip" | grep -i 'country:') 
    printf '%s\n' "$ip $country_line" 
done 

Альтернативный вариант, который будет работать со старыми (3.x) выпусками Баш, используя sort -u для генерации уникальных значений, а не делать это внутреннее к оболочке:

while read -r ip; do 
    case $ip in 66.33.*|66.128.*|75.102.*|216.106.*|66.6.*) continue;; esac 
    printf '%s\n' "$ip $(whois "$ip" | grep -i 'country:')" 
done < <(grep -E -o '[0-9]+[.][0-9]+[.][0-9]+[.][0-9]+' | sort -u) 

Это более эффективно выполнять перенаправление ввода и вывода для сценарий в целом чем поставить >> Перенаправление после самого printf (который откроет файл перед каждой операцией печати и закройте его снова после того, как, подвергаясь значительную производительность штраф), поэтому предложенный вызов для этого скрипта выглядит примерно так:

countries_for_addresses </path/to/logfile >/path/to/output 
+0

Это сработало. Теперь мне просто нужно добавить бит для grep -v '66 .33 \ | 66.128 \ | 75.102 \ | 216.106 \ | 66.6 ', и я сделаю это. – user3788019

+0

Может также реализовать эту логику в bash. 'case $ ip в 66.33. * | 66.128. * | 75.102. * | 216.106. * | 66.6. *) continue ;; esac' –

+0

@ user3788019, ... мое предложение выше на самом деле является штрихом менее багги, поскольку он соответствует этим строкам только в позиции префикса, а не также исключает '1.2.66.6' или' 1.66.6.2', хотя вы также можете переписать ваш grep: 'grep -E -v '^ (66 [.] 33 | 66 [.] 128 | 75 [.] 102 | 216 [.] 106 | 66 [.] 6)''. –