2015-12-29 41 views
0

我需要對包含IP地址的文件執行whois查找,並將國家代碼和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地址和國家代碼。不管它們是單列還是雙列。

下面是一些示例輸入:

年12月27四點03分30秒的sendmail smtpfive [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 = Deferred:451本次超過收件人限制 nder Dec 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,STAT =遞延:451收件人極限超過此瑟 的nDer

感謝。

+3

'awk |排序| uniq | grep | awk | bash | grep'聽起來有點過分。也許你可以提供一個樣例'myInputFile'和期望的輸出,所以我們可以提出一個更好的方法。 – fedorqui

+0

僅供參考,在'done'之後放置'> whatever'更有效,而不是每次要運行'whois'命令時重新打開該文件。 –

+0

另外,我全心全意地同意@fedorqui - 我無法想象你的管道不能完全歸結爲兩個元素而不再是其他情況。(請記住'awk'可以做排序,統一和反轉或其他) –

回答

2

一般:迭代你的輸入作爲shell變量;這可以讓你將它們打印在shell的每個輸出旁邊。


的下面將使用bash 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 

一個替代版本,這將在bash的較舊的(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中實現該邏輯。 「66.33美元的案例$ ip。* | 66.128。* | 75.102。* | 216.106。* | 66.6。*)繼續;; 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)''。 –