47

我正在尝试从我的 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,这不会改变任何内容。

有什么提示吗?

4

6 回答 6

123

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

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
于 2014-03-25T03:09:52.490 回答
20

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

awk '{ print $1 }' /var/log/*access*log | sort -n | uniq -c | sort -nr | head -20
于 2014-12-06T16:15:36.593 回答
4

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

cat access.* | awk '{ print $1 } ' | sort | uniq -c | sed -r 's/^[ \t]*([0-9]+) (.*)$/\1 --- \2/' | sort -rn
于 2014-03-26T14:47:08.843 回答
2

这应该工作

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

我看不出有什么问题。

文件中的控制字符?

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

于 2013-09-08T15:24:48.853 回答
0

如果排序没有按预期产生,可能是由于语言环境问题。

| 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

排序未按预期排序(空格和语言环境)

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

于 2018-07-30T08:52:46.727 回答
0

如果有人想要这里有 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; 
}  
于 2021-01-21T18:03:52.833 回答