apple
orange
apple
apple
orange
:
:
という改行区切りに単語が並んでいるリストがテキストに保存されています。
これらの単語は予測できないものとします。
このリストから
apple 5
lemon 4
orange 2
というように、出現した単語をすべてリストアップし、個数を数え、多い順に並べ替え、表示または保存する、というようなことをしたいです。
SQL で言うならば
SELECT 単語,count(*) FROM 単語リスト GROUP BY 単語 ORDER BY count(*) DESC
と同じことを、シェルスクリプトだけで行いたいのです。
環境は RHEL または CentOS の 5.x 系で、 Web用途ではないマシンのため、各種CGIやデータベースは入れてません。
何か良いアイデアはないでしょうか。
cat FILE | sort | uniq -c | sort -nr | awk '{print $2,$1}'
で FILE に入っている単語を表示できます。
出力をファイルにリダイレクトすればファイルにも保存可能です。
個数が冒頭に表示されても良ければ、1行でできます。
ターゲットのテキストは "hoge.txt" に記されているとします。
sort hoge.txt | uniq -c | sort -r
マニュアル読んだら良いと思うよ。
> マニュアル読んだら良いと思うよ。
マニュアル上の解釈だと
uniq -c は [個数] [文字列] のフィールド順で出力されますから、
目的からすれば -k 2 ではなくて -k 1 なんですよね。
ところが、並べ替えの結果はちゃんと数字の多い順になっています。
ここが「良く分からない」と表現した部分です。
cat sample.txt | sort | uniq -c | sort -k 2
だとちゃんと文字列のフィールドで ABC 順になるようなので、
-n オプションがある場合 -k オプションが無視されてるような気が。
正解。つまりは自分の記述ミスでした。ゴメンナサイ。
>並べ替えの結果はちゃんと数字の多い順になっています。
これは想定していなかったな。たまたまではないだろうか。
まぁこれだけでは申し訳ないので、大抵の環境で使えて多分早いだろう方法を。
# perl -n -e 'chomp; $h{$_}++; END { for( sort { $h{$b} <=> $h{$a} } keys %h ) { print "$_\t$h{$_}" } }' sample.txt