删除重复条目并将其替换为逗号 |重击

删除重复条目并将其替换为逗号 |重击

我有一个文件,其中包含按以下顺序的 IP 地址和端口号:

IP地址:端口

1.1.1.1:21
1.1.1.1:22
2.2.2.2:443
3.3.3.3:80
3.3.3.3:443

我需要以下格式的结果

ipaddress : port, port

1.1.1.1:21,22
2.2.2.2:443
3.3.3.3:80,443

答案1

假设输入文件中的行没有尾随空格:

$ awk -F ':' 'BEGIN { OFS=FS } $1 in ports { ports[$1] = ports[$1] "," $2; next } { ports[$1] = $2 } END { for (ip in ports) print ip, ports[ip] }' file
3.3.3.3:80,443
1.1.1.1:21,22
2.2.2.2:443

剧本awk

BEGIN       { OFS=FS }
$1 in ports { ports[$1] = ports[$1] "," $2; next }
            { ports[$1] = $2 }
END         { for (ip in ports) print ip, ports[ip] }

首先将输出字段分隔符设置为与输入字段分隔符相同,输入字段分隔符是一个:字符(在命令行上用 给出-F ':'),然后它会测试当前的第一个字段(IP 地址)是否是键数组ports。如果是,则将端口号(第二个字段)添加为该数组条目的逗号作为分隔符。如果不是,则数组中的条目将简单地设置为该 IP 地址的端口号。

最后,所有存储的 IP 地址都将与其收集的端口号一起打印。

答案2

GNU 数据整合

datamash -t: -s groupby 1 collapse 2 < file

如果您的数据已经排序,则可以省略-s.


或者在 Perl 中的散列中使用匿名数组:

$ perl -F: -lne '
    push @{ $h{$F[0]} }, $F[1] 
    }{ 
    for $k (sort keys %h) {print "$k:", join ",", @{ $h{$k}} }
' file
1.1.1.1:21,22
2.2.2.2:443
3.3.3.3:80,443

答案3

使用米勒(http://johnkerl.org/miller/doc) 是

mlr --nidx --fs ':' nest --implode --values --across-records --nested-fs "," -f 2 input

它给你回馈

1.1.1.1:21,22
2.2.2.2:443
3.3.3.3:80,443

答案4

您可以使用sed 编辑器来完成。我们在模式空间中随时维护 2 条线,并查找 IP 号的变化。只要我们继续获得相同的 IP,我们就会从第二部分中删除该 IP,并用逗号将其与第一部分连接起来。如果没有,则意味着已检测到 IP 更改,我们立即仅打印第一部分,将其从模式空间中删除,然后返回并将下一个 IP 行读入模式空间并重复相同的检查。

$ sed -e '
    :loop
       $!N
       s/^\(\([^:]*:\).*[^[:space:]]\).*\n\2/\1,/
    tloop
    P;D
 ' input-file.txt

 1.1.1.1:21,22
 2.2.2.2:443 
 3.3.3.3:80,443

 $ perl -lne '
    my($ip, $port) = /(\H+):(\H+)/;
    push @seen, $ip if ! exists $h{$ip};
    push @{$h{$ip}}, $port;}{
    print $_,  ":", join ",", @{$h{$_}} for @seen;
 ' input-file.txt

使用 Perl,我们可以通过散列来执行相同的操作,该散列将维护 IP 作为其键,并将数组引用作为包含端口的值。此外,我们确保不考虑任何尾随空格。数组 @seen 按照 IP 出现的顺序维护它们。

相关内容