下記のことがシェルスクリプトだけでできるかどうか教えてください。


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やデータベースは入れてません。
何か良いアイデアはないでしょうか。

回答の条件
  • 1人2回まで
  • 登録:
  • 終了:2009/06/27 01:15:06
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:a4w No.1

回答回数25ベストアンサー獲得回数2

ポイント30pt

cat FILE | sort | uniq -c | sort -nr | awk '{print $2,$1}'

で FILE に入っている単語を表示できます。

出力をファイルにリダイレクトすればファイルにも保存可能です。

id:chocococoa

すばやいご回答、ありがとうございます。

全てにおいて適した結果になっております。

2009/06/27 01:08:15

その他の回答3件)

id:a4w No.1

回答回数25ベストアンサー獲得回数2ここでベストアンサー

ポイント30pt

cat FILE | sort | uniq -c | sort -nr | awk '{print $2,$1}'

で FILE に入っている単語を表示できます。

出力をファイルにリダイレクトすればファイルにも保存可能です。

id:chocococoa

すばやいご回答、ありがとうございます。

全てにおいて適した結果になっております。

2009/06/27 01:08:15
id:pahoo No.2

回答回数5960ベストアンサー獲得回数633

ポイント25pt

個数が冒頭に表示されても良ければ、1行でできます。

ターゲットのテキストは "hoge.txt" に記されているとします。

sort hoge.txt | uniq -c | sort -r
id:chocococoa

最低限パイプ2つあれば良いというシンプルなご回答ですね。

理解しやすいです。ありがとうございます。

2009/06/27 01:02:49
id:b-wind No.3

回答回数3344ベストアンサー獲得回数440

ポイント20pt
$ cat sample.txt | sort | uniq -c | sort -k 2 -n -r 

Manpage of SORT

Manpage of UNIQ

id:chocococoa

ありがとうございます。こちらも問題なく動きました。

ただ、 -k 2 が意味するところが良く分からないです。

2009/06/27 01:11:31
id:sphire No.4

回答回数115ベストアンサー獲得回数12

ポイント20pt
$ cat hoge.txt | sort | uniq -c | sed 's/^ *\([0-9]*\) *\(.*\)$/\2 \1/'
id:chocococoa

ありがとうございます。 sed により表示もバッチリです。

ただ、要件の「多い順に並べ替え」ができませんでした。

2009/06/27 01:14:11
  • id:b-wind
    >ただ、 -k 2 が意味するところが良く分からないです。
    マニュアル読んだら良いと思うよ。
  • id:chocococoa
    chocococoa 2009/06/27 11:37:06
    > >ただ、 -k 2 が意味するところが良く分からないです。
    > マニュアル読んだら良いと思うよ。

    マニュアル上の解釈だと
    uniq -c は [個数] [文字列] のフィールド順で出力されますから、
    目的からすれば -k 2 ではなくて -k 1 なんですよね。

    ところが、並べ替えの結果はちゃんと数字の多い順になっています。
    ここが「良く分からない」と表現した部分です。

    cat sample.txt | sort | uniq -c | sort -k 2
    だとちゃんと文字列のフィールドで ABC 順になるようなので、
    -n オプションがある場合 -k オプションが無視されてるような気が。
  • id:b-wind
    >目的からすれば -k 2 ではなくて -k 1 なんですよね。
    正解。つまりは自分の記述ミスでした。ゴメンナサイ。

    >並べ替えの結果はちゃんと数字の多い順になっています。
    これは想定していなかったな。たまたまではないだろうか。

    まぁこれだけでは申し訳ないので、大抵の環境で使えて多分早いだろう方法を。
    # perl -n -e 'chomp; $h{$_}++; END { for( sort { $h{$b} <=> $h{$a} } keys %h ) { print "$_\t$h{$_}" } }' sample.txt

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません