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

Lining up pipeline results alongside input (here, "ip" and whois grep results)

我需要对包含 IP 地址的文件执行 whois 查找,并将国家代码和 IP 地址都输出到一个新文件中。到目前为止,在我的命令中,我找到了 IP 地址并获得了一个与允许范围不匹配的唯一副本。然后我 运行 进行 whois 查找以找出谁是外国地址。最后它拉出国家代码。这很好用,但我无法让它在国家代码旁边显示 IP,因为它不包含在 whois 输出中。

在输出中包含 IP 地址的最佳方式是什么?

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

我曾考虑过使用 tee,但在以合理的方式排列数据时遇到了问题。输出文件应该有 IP 地址和国家代码。不管是单列还是双列。

这是一些示例输入:

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=Deferred: 451 Recipient limit exceeded for this se 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=Deferred: 451 Recipient limit exceeded for this 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 '%s\n' "$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 '%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