【问题标题】:Sort uniq IP address in from Apache log从 Apache 日志中排序 uniq IP 地址
【发布时间】:2013-09-12 00:02:59
【问题描述】:

我正在尝试从我的 apache 日志中提取 IP 地址,对它们进行计数并对其进行排序。

无论出于何种原因,排序部分都很糟糕。

命令如下:

cat access.* | awk '{ print $1 }' | sort | uniq -c | sort -n

输出示例:

  16789 65.X.X.X
  19448 65.X.X.X
   1995 138.X.X.X
   2407 213.X.X.X
   2728 213.X.X.X
   5478 188.X.X.X
   6496 176.X.X.X
  11332 130.X.X.X

我不明白为什么这些值没有真正排序。我还尝试删除行首的空白 (sed 's/^[\t ]*//g') 并使用 sort -n -t" " -k1,这不会改变任何内容。

有什么提示吗?

【问题讨论】:

    标签: apache bash sorting logging


    【解决方案1】:

    这可能会迟到,但在第一次排序中使用数字会给你想要的结果,

    cat access.log | awk '{print $1}' | sort -n | uniq -c | sort -nr | head -20
    

    输出:

     29877 93.xxx.xxx.xxx
      17538 80.xxx.xxx.xxx
       5895 198.xxx.xxx.xxx
       3042 37.xxx.xxx.xxx
       2956 208.xxx.xxx.xxx
       2613 94.xxx.xxx.xxx
       2572 89.xxx.xxx.xxx
       2268 94.xxx.xxx.xxx
       1896 89.xxx.xxx.xxx
       1584 46.xxx.xxx.xxx
       1402 208.xxx.xxx.xxx
       1273 93.xxx.xxx.xxx
       1054 208.xxx.xxx.xxx
        860 162.xxx.xxx.xxx
        830 208.xxx.xxx.xxx
        606 162.xxx.xxx.xxx
        545 94.xxx.xxx.xxx
        480 37.xxx.xxx.xxx
        446 162.xxx.xxx.xxx
        398 162.xxx.xxx.xxx
    

    【讨论】:

    • 我完全忘记了这个问题,但我设法找到了解决方案。这不起作用(见我的问题)。但是在数字和 IP 之间添加非数字字符解决了我的问题。
    • 投反对票:答案完全没有改变,实际答案是亚瑟的评论
    • 我如何在 Apache 的 ssl_request_log 上使用它,因为我们所有的洪水都是通过 ssl 进行的
    【解决方案2】:

    为什么使用cat | awk?你只需要使用awk

    awk '{ print $1 }' /var/log/*access*log | sort -n | uniq -c | sort -nr | head -20
    

    【讨论】:

      【解决方案3】:

      我不知道为什么简单的sort -n 不起作用,但是在计数器和 IP 之间添加一个非数字字符解决了我的问题。

      cat access.* | awk '{ print $1 } ' | sort | uniq -c | sed -r 's/^[ \t]*([0-9]+) (.*)$/\1 --- \2/' | sort -rn
      

      【讨论】:

      • 有时值得排除一些状态和机器人cat access.log |grep -v -w 200 | grep -v -w 403 | grep -v -e '.jpg'|grep -v -i bot | awk '{print $1}' | sort -n | uniq -c | sed -r 's/^[ \t]*([0-9]+) (.*)$/\1 --- \2/' | sort -nr | head -200
      • 请看我的回答...在我这边我有同样的问题,发现它与 LOCALE 和排序命令有关
      【解决方案4】:

      这应该可行

      cat access.* | awk '{ print $1 }' | sort | awk '{print $1 " " $2;}' | sort -n
      

      我看不出有什么问题。

      文件中的控制字符?

      文件系统已满(临时文件)?

      【讨论】:

        【解决方案5】:

        如果排序结果未达到预期,可能是由于语言环境问题。

        | LC_ALL=C sort -rn

        awk '{array[$1]++}END{ for (ip in array) print array[ip] " " ip}' <path/to/apache/*.log> | LC_ALL=C sort -rn
        

        来源 sort not sorting as expected (space and locale)

        https://www.commandlinefu.com/commands/view/9744/sort-ip-by-count-quickly-with-awk-from-apache-logs

        【讨论】:

          【解决方案6】:

          如果有人想要这里有 PHP 函数,它可以计算哪个 ip 在文件中出现了多少次。

          function get_access_ip_count($input_file_name, $output_file_name){
              
              $access_ip_array = array();
              
              $overall_count = 0;
              
              $handle = fopen($input_file_name, "r");
              if ($handle) {
                  
                  while (($line = fgets($handle)) !== false) {
                      
                      preg_match('/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/', $line, $matches);
                      
                      #print_r($matches);
                      #exit;
                      
                      if($matches[0]>0){
                          
                          #print_r($matches);
                          
                          $ip = $matches[0];
                          #echo "ip: $ip";
                          if(!isset($access_ip_array[$ip])){
                              
                              $access_ip_array[$ip] = 1;
                              $overall_count++;
                              
                          }
                          else{
                              
                              $access_ip_array[$ip]++;
                              $overall_count++;
                              
                          }
                          
                      }
                  }
                  fclose($handle);
                  
                  uasort($access_ip_array,"Descending");
                  
                  echo "<pre>";
                  print_r($access_ip_array);
                  echo "</pre>";
                  
                  $output_file = fopen($output_file_name, "w");
                  fwrite($output_file, print_r($access_ip_array, TRUE));
                  fclose($output_file);
                  
                  echo "overall_count: $overall_count";
                  
              } else {
                  echo "Couldn't open file";
              } 
          }
          
          function Descending($a, $b) {   
              if ($a == $b) {        
                  return 0;
              }   
                  return ($a > $b) ? -1 : 1; 
          }  
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2015-05-30
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-05-18
            • 2018-07-19
            • 2021-05-25
            相关资源
            最近更新 更多