将管道结果与输入对齐(此处为 "ip" 和 whois grep 结果)



我需要对包含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

相关内容

最新更新