我需要对包含IP地址的文件执行whois查找,并将国家代码和IP地址输出到一个新文件中。到目前为止,在我的命令中,我找到了IP地址,并获得了一个与允许范围不匹配的唯一副本。然后我运行whois查找来找出谁是外国地址。最后,它拔出了国家代码。这很好,但我无法让它显示IP和国家代码,因为whois输出中不包括这些代码。
在输出中包含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
我曾想过使用tee,但在以合理的方式排列数据时遇到了问题。输出文件应同时具有IP地址和国家/地区代码。它们是单列还是双列都无关紧要。
以下是一些示例输入:
12月27日04:03:30 smtpfive sendmail[14851]:tBRA3HAx014842:to=,delay=00:00:12,xdelay=00:00:01,mailer=esmtp,pri=1681345,relay=redcondor.itcetel.com.[75.102.160.236],dsn=4.3.0,stat=递延:超过451此se的收件人限制nder12月27日04:03:30 smtpfive sendmail[14851]:tBRA3HAx014842:to=,delay=00:00:12,xdelay=00:00:01,mailer=esmtp,pri=1681345,relay=redcondor.itcetel.com.[75.102.160.236],dsn=4.3.0,stat=递延:超过451此se的收件人限制nder
谢谢。
通常:将输入作为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 '%sn' "$ip $country_line"
done
另一个版本将与bash的旧版本(3.x)一起使用,使用sort -u
生成唯一值,而不是在shell内部这样做:
while read -r ip; do
case $ip in 66.33.*|66.128.*|75.102.*|216.106.*|66.6.*) continue;; esac
printf '%sn' "$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