使用标准命令行工具解析命令输出中的所有 IP 地址

使用标准命令行工具解析命令输出中的所有 IP 地址

我有几个包含大量 IP 地址的日志文件。我希望能够通过一个能够匹配和解析 IP 地址的程序来传输数据。

IE 猫 /var/log/somelogfile |主持人

这会变成一条线

10:45 于 10.13.13.10 访问

进入

10:45 通过 myhostname.intranet 访问

我的想法是可能有一种方法可以结合使用 sed 和 host 来做到这一点,但我不知道该怎么做。我知道我可以编写一个简单的脚本来完成此操作,但如果可能的话,我宁愿能够使用内置工具。有什么建议么?

答案1

这是 Python 中的一个快速但肮脏的解决方案。它进行缓存(包括负缓存),但没有线程,并且不是您见过的最快的东西。如果将其保存为类似的名称rdns,则可以这样调用:

zcat /var/log/some-file.gz | rdns
# ... or ...
rdns /var/log/some-file /var/log/some-other-file # ...

运行它将使用其 PTR 记录来注释 IP 地址:

$ echo "74.125.132.147, 64.34.119.12." | rdns
74.125.132.147 (rdns: wb-in-f147.1e100.net), 64.34.119.12 (rdns: stackoverflow.com).

这是来源:

#!/usr/bin/env python

import sys, re, socket

cache = dict()

def resolve(x):
    key = x.group(0)
    try:
        return "%s (rdns: %s)" % (key, cache[key])
    except KeyError:
        try:
            cache[key] = socket.gethostbyaddr(key)[0]
        except socket.herror:
            cache[key] = '?'
        return "%s (rdns: %s)" % (key, cache[key])

for f in [open(x) for x in sys.argv[1:]] or [sys.stdin]:
    for line in f:
        sys.stdout.write(re.sub("\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}", resolve, line))

# End of file.

请注意:这并不完全是您所追求的(使用“标准工具”)。但它可能比每次遇到 IP 地址时都解析它的 hack 更能帮助您。通过多几行,您甚至可以让它持久缓存其结果,这将有助于重复调用。

答案2

我会用jdresolve -n -a

为 debian 等打包的也可以在:

https://github.com/jdrowell/jdresolve

    jdresolve 将 IP 地址解析为主机名。任何文件格式都是
    支持,包括线路不以 IP 开头的情况
    地址。

十多年来我一直使用它来解析 apache 日志、squid 日志以及任何其他需要解析的具有大量 IP 地址的内容。它运行良好、可靠且快速,并且可以缓存以前运行的查找。

答案3

一个 bash 脚本,您可以捕获日志文件并通过管道输入。

#!/bin/bash

while read input; do

    for arg in $( echo $input ); do
            match=$(echo "$arg" | grep -P '([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])' )
            if [ "x${match}" = "x" ]; then
                    printf "%-s" "$arg "
            else
                    dns=$( host $arg | tail -1 | awk '{print $NF}' 2>/dev/null )
                    if [ "${dns}" == "3(NXDOMAIN)" ]; then
                            printf "%-s" "$arg "
                    else
                            if [ "x${dns}" == "x" ]; then
                                    printf "%-s" "$arg "
                            else
                                    printf "%-s" "$dns "
                            fi
                    fi
            fi
    done
done
printf "\n"

输出看起来像:

tk-air:~ tim$ echo "10:45 accessed by 8.8.8.8" | ./get-dns 
10:45 accessed by FWDR-8.FWDR-8.FWDR-8.FWDR-8. 

tk-air:~ tim$ echo "10:45 accessed by 8.8.8.8 26 times" | ./get-dns 
10:45 accessed by FWDR-8.FWDR-8.FWDR-8.FWDR-8. 26 times 

答案4

如果日志格式始终显示与上面显示的相同,那么您可以使用以下命令来执行此操作echo 10:45 accessed by 10.13.13.10|awk '{print $4}'|nslookup

相关内容