uniq -c コマンド形式の変更

uniq -c コマンド形式の変更

ファイル内の一意の単語とその数を取得したいと思います。次のコマンドを実行すると、

sort words.txt | uniq -c



   2 america
   4 and
   1 england
   1 file
   1 for
   1 place

しかし、次の形式で出力したいです。

america,2
and,4
england,1
file,1
for,1
place,1

私の入力ファイルは約30〜40 Gbです。それでは、この形式で出力を印刷する最良の方法は何ですか?

答え1

awkコマンドの最後に行を追加できます。例えば、

sort words.txt | uniq -c | awk '{print $2","$1}'

デフォルトでは、最初の列の前に2番目の列をカンマで区切って配置します。 30-40Gbファイルでこれを実行するのにどれくらいの費用がかかっているのかわかりません。

答え2

awk自体を使用してこれを行うことができます...

以下で試してください。

awk '{j[$0]++} END {for (i in j) print i","j[i]}' words.txt

答え3

そしてsed

sort words.txt | uniq -c | sed -E 's/^ *([0-9]) (.+)/\2,\1/g' 

GNU、Busybox、BSDの実装でテストされていますsed。出力は次のとおりです。

america,2
and,4
england,1
file,1
for,1
place,1

200MBファイルでテストした結果、それsed自体はまだかなり高速であることがわかりました。

$ time sed  -E 's/^ *([0-9]) (.+)/\2,\1/g'  HUGE | head
america,2
and,4
england,1
file,1
for,1
place,1
america,2
and,4
england,1
file,1

real    0m0.006s
user    0m0.003s
sys     0m0.006s

-i ただし、これら2つのオプションを使用して>シェル演算子を使用して出力をリダイレクトすると、データをディスク上のファイルに保存するのに時間がかかります。

$ time sed -i -E 's/^ *([0-9]) (.+)/\2,\1/g'  HUGE
real    0m45.793s
user    0m31.965s
sys     0m13.574s
$ time sed -E 's/^ *([0-9]) (.+)/\2,\1/g'  HUGE > HUGE_NO_I
real    0m29.016s
user    0m28.684s
sys     0m0.119s

関連情報