【问题标题】:Replace IPs with Hostnames in a log在日志中用主机名替换 IP
【发布时间】:2012-04-04 13:57:09
【问题描述】:

我正在寻找一个 bash 脚本,它可以读取日志并用主机名替换 IP 地址。有没有人知道如何做到这一点?

【问题讨论】:

  • 我尝试在 Stack Overflow 上发帖,但一直在等待答案。
  • IPv4 或 IPv6 或两者兼而有之? /etc/hosts 中有主机名吗?

标签: linux bash dns ip-address


【解决方案1】:

以下脚本应该可以工作。你可以这样使用它:

将其保存到 ip_to_hostname.sh 然后:

./ip_to_hostname.sh your_logfile > resolved_ip

#!/bin/bash

logFile=$1

while read line
do
        for word in $line
        do
                # if word is ip address change to hostname
                if [[ $word =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]
                then
                        # check if ip address is correct
                        OIFS=$IFS
                        IFS="."
                        ip=($word)
                        IFS=$OIFS
                        if [[ ${ip[0]} -le 255 && ${ip[1]} -le 255 && ${ip[2]} -le 255 && ${ip[3]} -le 255 ]]
                        then
                                echo -n `host $word | cut -d' ' -f 5`
                                echo -n " "
                        else
                                echo -n "$word"
                                echo -n " "
                        fi
                # else print word
                else
                        echo -n $word
                        echo -n " "
                fi
        done
        # new line
        echo
done < "$logFile"

【讨论】:

  • 这个脚本运行良好。事后看来,我应该更好地描述我的日志格式。 (它来自 Netgear 路由器)我做了一些细微的修改,这就像一个魅力,谢谢!
【解决方案2】:

谈论 IPv4:您可以从 hosts 文件中生成一个 sed 命令列表:

sed -rn 's/^(([0-9]{1,3}\.){3}([0-9]{1,3}))[ \t]([^ \t]+)[ \t].*/s#\1#\4#/p' /etc/hosts > hosts.sed 

然后将其应用到您的日志文件中:

sed -f hosts.sed LOGFILE

当然,您的主机文件名必须列在主机文件中。

另一种相反的方法是使用 logresolve

来自手册页:

NAME
   logresolve - Resolve IP-addresses to hostnames in Apache log files

SYNOPSIS
   logresolve [ -s filename ] [ -c ] < access_log > access_log.new

SUMMARY
   logresolve is a post-processing program to resolve IP-addresses in Apache's access logfiles. To minimize
   impact on your nameserver, logresolve has its very own internal hash-table cache. This means  that  each
   IP number will only be looked up the first time it is found in the log file.

   Takes  an  Apache  log file on standard input. The IP addresses must be the first thing on each line and
   must be separated from the remainder of the line by a space.

因此您可以使用 REGEX 提取所有 IP,将它们 2 次放入一个新文件中,一次放入第一列,然后使用 logresolve 进行转换。然后使用此表生成如上这样的 sedfile。

【讨论】:

    【解决方案3】:

    解析可以这样完成:

    ip=72.30.38.140
    主机名=nslookup $ip | grep name
    主机名=${主机名#*name = }
    主机名=${主机名%.}

    这样 IP 不必在 /etc/hosts 中。

    脚本本身取决于您的日志的外观。可以举个例子吗?

    【讨论】:

    • 当心使用 sed 进行替换时的常见错误。想想如果你有 IP 72.30.38.140 和 72.30.38.14 会发生什么。当您替换 72.30.38.14 时,它也会在 72.30.38.140 中被替换,因为它包含 72.30.38.14。您必须替换为 IP 字段分隔符。
    【解决方案4】:

    这是我最终使用的 wisent 脚本的修改版本:

    #!/bin/bash
    
    logFile=$1
    
    while read line
    do
           for word in $line
           do
                   # if word is ip address change to hostname
                   if [[ $word =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\:[0-9]{1,5}$ ]]
                   then
                           port=$(echo "$word" | sed -e "s/.*://")
                           word=$(echo "$word" | sed -e "s/:.*//")
                           OIFS=$IFS
                           IFS="."
                           ip=($word)
                           IFS=$OIFS
                           # check if ip address is correct and not 192.168.*
                           if [[ ${ip[0]} -le 255 && ${ip[1]} -le 255 && ${ip[2]} -le 255 && ${ip[3]} -le 255 && ${ip[0]}${ip[1]} -ne 192168 ]]
                           then
                                   host=$(host $word | cut -d' ' -f 5)
                                   if [[ $host =~ ^[0-9]{1,3}\(.*\)$ ]] # check for resolver errors
                                   then
                                           # if the resolver failed
                                           echo -n "$word"
                                           echo -n ":$port"
                                           echo -n " "
                                   else
                                           # if the resolver worked
                                           host=$(echo "$host'" | sed -e "s/\.'//" | sed ':a;N;$!ba;s/.*\n//g') # clean up cut's output
                                           echo -n "$host"
                                           echo -n ":$port"
                                           echo -n " "
                                   fi
                           else
                                   # if the ip address isn't correct
                                   echo -n "$word"
                                   echo -n ":$port"
                                   echo -n " "
                           fi
                   # else print word
                   else
                           echo -n $word
                           echo -n " "
                   fi
           done
           # new line
           echo
    done < "$logFile"
    

    【讨论】:

      【解决方案5】:

      前段时间我将它添加到我的 .bashrc...

      function resolve-hostname-from-ip()
      {
          if [ ! $1 ]
          then 
              echo -e "${red}Please provide an ip address...${no_color}"
              return 1
          fi
          echo "" | traceroute $1|grep " 1 "|cut -d ' ' -f4|cut -d '.' -f1
      }
      

      我有预定义的终端颜色,因此您可以根据需要省略这些颜色。 =D

      [root@somehostname ~ 08:50 AM] $ resolve-hostname-from-ip 111.22.33.444
      someotherhostname
      

      我已经在 RHEL 和 SUSE 上成功地测试了这个。不过,我还没有在我的域之外的 IP 上测试过它,所以我不能 100% 确定它在所有情况下都能正常工作......希望这会有所帮助 =)

      【讨论】:

        猜你喜欢
        • 2019-05-02
        • 2015-04-12
        • 1970-01-01
        • 1970-01-01
        • 2015-01-02
        • 1970-01-01
        • 2022-08-17
        • 2014-04-12
        • 1970-01-01
        相关资源
        最近更新 更多