-2

我是 unix 新手。我正在尝试通过文件中某个列中值的出现来对文件进行排序:

IP    - - Website
1.1.1 - - stackoverflow.com
0.0.5 - - a.com 
1.1.1 - - google.com

预期结果:

IP    - - Website
1.1.1 - - stackoverflow.com
0.0.5 - - a.com

我尝试了不同的方法:

  • sort -k1 | uniq -c(没用,因为 uniq 检查了整行,包括网站)
  • 使用sort -u -t- -k1

谁能帮助我,或者至少请告诉我我做错了什么?

编辑:我找到了一种更好的方法: egrep -o '[[:digits:]]{1,3}.[[:digits:]]{1,3}.[[:digits:]]{1 ,3}'|排序-g | 唯一的-c | sort -gr (希望有一天这会对某人有所帮助)

4

4 回答 4

2

你可以给一个机会。-它根据中间的字段将行拆分为两个字段,并将内容保存在哈希中以便以后对它们进行排序。在散列中,键是 IP,值是数组引用,其中包含每个 IP 出现的计数器和原始行。

假设infile内容:

IP    - - Website
2.2.2 - - yahoo.es
1.1.1 - - in.google.com
0.0.5 - - a.com 
1.1.1 - - google.com
1.1.1 - - gmail.google.com
2.2.2 - - yahoo.com

并执行以下perl命令:

perl -lne '
    do { $header = $_; next } if $. == 1;
    my @f = split /\s+-\s+-\s+/;
    if ( ! exists $ips{ $f[0] } ) {
        $ips{ $f[0] } = [ 1, $_ ];
    }
    else {
        $ips{ $f[0] }[0] += 1;
    }
    END {
        printf qq|%s\n|, $header;
        for my $key ( sort { $ips{ $b }[0] <=> $ips{ $a }[0] } keys %ips ) {
            printf qq|%s\n|, $ips{ $key }[1];
        }
    }
' infile

它产生:

IP    - - Website
1.1.1 - - in.google.com
2.2.2 - - yahoo.es
0.0.5 - - a.com
于 2013-09-15T16:54:03.273 回答
2

您似乎要求删除任何具有重复第一个字段的行。这可以通过以下awk一行来实现:

$ awk '!a[$1]++' file
IP    - - Website
1.1.1 - - stackoverflow.com
0.0.5 - - a.com
于 2013-09-15T17:03:04.980 回答
0

简单的外壳解决方案...

egrep -o '^[0-9\.]+' myfile.txt | sort | uniq -c | sort -nr
于 2013-09-19T20:28:15.650 回答
-1

uniq可以忽略指定数量的字符后的其余行-w

sort -r -k1 file | uniq -w5

uniq -w不是 POSIX,但如果你碰巧在一个相当最新的 Linux 上,它应该可以工作。

接下来我被告知,与垂直对齐的示例不同,第一个字段是可变长度的。应该知道,这是一个IP地址,笨!:) 在这种情况下,我在 IP 地址后添加 8 个空格以补偿最短 (7) 和最长 (15) 变体之间的差异,告诉 uniq 忽略第一个 15 个字符,然后将剩余的空格再次压缩为 1

sort -r -k1 file | sed 's/ /         /' | uniq -w15 | sed 's/  */ /'

没有 Perl。

于 2013-09-15T16:17:05.357 回答