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


8

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

IE cat / var / log / somelogfile | 主办

这会变成一条线

10:13被10.13.13.10访问

进入

由myhostname.intranet访问的10:45

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


2
通常不执行此操作的原因是因为执行所有这些PTR查询可能会慢。缓存结果(可能是持久保存)的多线程脚本(例如,Python)将是最好的。
Alexios 2012年

Answers:


8

这是Python中快速而肮脏的解决方案。它可以缓存(包括负缓存),但是没有线程,也不是您看到的最快的东西。如果将其另存为rdns,则可以这样命名:

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

运行它会注释IP地址以及它们的PTR记录:

$ 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都更有用。再增加几行,您甚至可以使它持久地缓存其结果,这将有助于重复调用。


感谢您的脚本。正是我想要的。我希望找到一种不需要编写脚本的解决方案,但这可能是下一件好事。
丹尼尔(Daniel)

3

我会用 jdresolve -n -a

为debian等打包,也可以在以下位置获得:

https://github.com/jdrowell/jdresolve

    jdresolve将IP地址解析为主机名。任何文件格式是
    支持,包括那些行不是以IP开头的
    地址。

我已经使用它十多年了,以解决apache日志,squid日志以及任何其他需要解析的IP地址的问题。它运行良好,可靠且快速,并且可以缓存以前运行的查询。


2

一个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 


1

如果日志格式始终显示与上面显示的相同,则可以使用 echo 10:45 accessed by 10.13.13.10|awk '{print $4}'|nslookup

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.