重複したエントリを削除してコンマで置き換えます。

重複したエントリを削除してコンマで置き換えます。

次の順序で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が必要です。

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。その場合は、ポート番号(2番目のフィールド)を配列エントリにカンマ区切り文字として追加します。そうでない場合、配列のエントリはその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を取得し続ける限り、2番目の部分からその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 が現れる順番に保持されます。

関連情報