与えられた入力:
144.252.36.69
afrloop=32235330165603
144.252.36.69
afrloop=32235330165603
144.252.36.69
afrloop=32235330165603
222.252.36.69
afrloop=31135330165603
222.252.36.69
afrloop=31135330165603
222.252.36.69
afrloop=31135330165603
222.252.36.69
afrloop=31135330165603
どのように出力できますか?
144.252.36.69
afrloop=32235330165603 3 times
222.252.36.69
afrloop=31135330165603 4 times
答え1
paste - - < file | sort | uniq -c
答え2
awk
カスタム出力形式が必要な場合はこれが解決策です
NR%2==1 {ip=$0; next}
NR%2==0 {a[ip"\n"$0]++}
END {
for(i in a)
printf "%s %d times\n", i, a[i]
}
スクリプトは次のように実行できます。
awk -f main.awk file
説明する
まず、奇数モジュロ2が1に等しいため、奇数行を一致させるために使用します
NR%2==1
。行がこの条件と一致すると、行全体が名前付き$0
変数に保存されますip
。これを使用してnext
追加の処理をスキップし、次の繰り返しに直接移動できます。第二に、偶数行を一致させるために使用します
NR%2==0
。行が一致すると、ip"\n"$0
配列にインデックスを作成し、a
その特定のインデックスの数値を増やします。たとえば、同等の拡張は次のとおりです。a["144.252.36.69 afrloop=32235330165603"] += 1
\n
簡単にするために、この例では新しい行を無視しています。最後に
END
、各行を処理した後、ループを使用してfor
配列内の各要素値a
(この場合は各固有インデックスの数)を印刷します。
面白いベンチマーク
テストファイルの生成(100万レコード)
awk ' BEGIN{for(i=1;i<10000000;i++) printf "%d\nafrLoop=%d\n", int(rand()*100), int(rand()*10)} ' > test $ head test 23 afrLoop=2 84 afrLoop=1 58
@n.caillouペーストソリューション
$ time paste - - < test | sort | uniq -c > /dev/null real 0m11.250s user 0m11.352s sys 0m0.272s
奇妙なソリューション
$ time awk -f main.awk test > /dev/null real 0m5.673s user 0m5.636s sys 0m0.036s