Bash:如何打印将 IP 地址与名称相匹配的附加列

Bash:如何打印将 IP 地址与名称相匹配的附加列

我用来netstat收集有关已连接 IP 的信息。我有以下格式:

netstat -tn 2>/dev/null | awk '/:80 / {print $5}' | sed 's/.*::ffff://' | sed 's/:.*//' | sor t | uniq -c | sort -nr
      5 81.133.113.200
      4 80.229.142.126
      2 94.136.36.29
      2 92.19.231.69
      2 85.159.56.230
      2 83.70.246.152
      2 81.131.118.236
      2 185.106.92.42
      1 92.19.232.88
      1 86.47.113.169
      1 86.168.206.46
      1 79.77.175.210
      1 46.19.141.238
      1 206.221.184.2
      1 192.198.95.6

我试图完成的是将 IP 与主机名相匹配。

所以如果我已经name=$(IPADDRESSNAME)存储在某个地方并且名称与 IP 地址 81.133.113.200 匹配

我希望它以这样的格式打印:

  5 81.133.113.200 - IPADDRESSNAME
  4 80.229.142.126
  2 94.136.36.29
  2 92.19.231.69

我一直在阅读专栏来尝试执行此操作,但我不确定如何将两列与地址上的匹配项结合起来。

我使用 Bash 脚本运行它,所以我会将主机名存储在其中。

我在想这样的事情:

string=$(netstat -tn 2>/dev/null | awk '/:80 / {print $5}' | sed 's/.*::ffff://' | sed 's/:.*//' | sort | uniq -c | sort -nr)
if [[ $string == "81.133.113.200" ]]
then
  echo "Its XXXXXXXX HOST";
fi

类似这样的东西,虽然这不起作用,但逻辑​​是在后面但内联的。

答案1

尝试一下这个经过测试的版本:

netstat -tn 2>/dev/null | awk '/:80 / {print $5}' | sed 's/.*::ffff://' | sed 's/:.*//' | sor t | uniq -c | sort -nr |\
while read index ipaddress ; do \
  printf "%s " "${index}" ;\
  getent hosts "${ipaddress}" ;\
  if [ $? -eq 2 ]; then \
    printf "%s\n" "${ipaddress}" ;\
  fi ;\
done

它正在使用标准获取来查询主机数据库以便根据给定的 IP 地址检索主机名。

考试:

5 81.133.113.200  host81-133-113-200.in-addr.btopenworld.com
4 80.229.142.126  garnerhome.plus.com
2 94.136.36.29    mail.e-trackit.co.uk
2 92.19.231.69    host-92-19-231-69.static.as13285.net
2 85.159.56.230
2 83.70.246.152   83-70-246-152-dynamic.b-ras1.prp.dublin.eircom.net
2 81.131.118.236  host81-131-118-236.range81-131.btcentralplus.com
2 185.106.92.42
1 92.19.232.88    host-92-19-232-88.static.as13285.net
...

答案2

我忘记了 Sed 可以用来追加一行而不仅仅是删除内容。所以我使用 Sed 来定位字符串并在其后添加一行。当你想一想时,相当简单。

我认为我在列中输出使情况变得过于复杂

以简单的一个衬垫为例:

  netstat -tn 2>/dev/null | awk '/:80 / {print $5}' | sed 's/.*::ffff://' | sed 's/:.*//' | sed '/8.8.8.8/s/$/ Its Google/' | sort | uniq -c | sort -nr

答案3

您可以逐行处理输出并根据您的要求进行打印。假设您想将 /etc/hosts 中的地址映射到主机名,您可以执行以下操作:

get_connected_hosts() {
  netstat -tn 2>/dev/null | awk '/:80 / {print $5}' | sed 's/.*::ffff://' | sed 's/:.*//' | sort | uniq -c | sort -nr
}

get_connected_hosts | while read line; do
  set -- $line
  result=$(grep $2 /etc/hosts | head -1 | awk '{ print $2 }')
  # or a reverse DNS lookup, result=$(dig +short -x $2)
  echo "$1 $2 - $result"
done | column -t

答案4

netstat -tn | awk '/:80 / {print $5}' | sed -e 's/:.*//' | 
    xargs -i sh -c 'echo {} $(getent hosts {})' | 
    awk '$1 == $2 {print $2, $3; next}; {print}' | 
    sort | uniq -c | sort -nr

(可以全部在一行上,我添加了换行以避免水平滚动条并使其更具可读性)

这使用xargs -i(使用隐式-L 1)进行getent hosts查找运行sort | uniq -c.这比需要的更复杂,因为getent如果查找不返回任何内容,则不会产生任何输出,因此我们需要通过echogetent.第二个awk确保每行仅打印一个 IP 地址。

其他替代方法是使用nslookup,dig -xhost -i进行 IP 到主机名查找,但所有这些都需要对输出进行更多处理。

第一行的after并不是真正需要的,我们可以在打印之前使用s函数进行同样的sed修改,但我认为这样做更具可读性和更容易理解。awkawkgsub()$5

相关内容