次の順序で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 が現れる順番に保持されます。