• ベストアンサー

Linuxシェルによる同一文字列のカウント集計

あるファイル中の同じ文字列の行をカウントして それぞれの文字列が何回現れるか集計するシェルを作ろうとしています。 しかし、最後のグループの集計がうまくいきません。 入力ファイルはソート済みです。 スコープの問題なのかどうか良くわかりませんが、想定外の動きをします。 このシェルの修正もしくは、別のいい集計方法、 どちらでも歓迎です。よろしくお願いします。 書いてみたシェル ------------------ #!/bin/sh TARGET_STR=`head -n 1 uniqData.txt` declare -i COUNT=0 cat uniqData.txt | while read LINE_STR do if [ "${TARGET_STR}" = "${LINE_STR}" ]; then COUNT=$COUNT+1 else echo $TARGET_STR:$COUNT TARGET_STR=${LINE_STR} COUNT=1 fi done echo $TARGET_STR:$COUNT ------------------ 入力ファイル ------------------ asd asd asd dfg dfg gghhjj gghhjj gghhjj gghhjj ttyyuuu ttyyuuu ttyyuuu wwee ------------------ 期待出力 ------------------ asd:3 dfg:2 gghhjj:4 ttyyuuu:3 wwee:1 ------------------ 実際の出力 ------------------ asd:3 dfg:2 gghhjj:4 ttyyuuu:3 asd:0 ------------------

質問者が選んだベストアンサー

  • ベストアンサー
  • OKwebb
  • ベストアンサー率44% (92/208)
回答No.2

回答としては#1の方法がベストだと思います。 参考までにシェルが希望通りに動作しないのは、 パイプ以降がサブシェルで動作するからです。 多分asdの行数が1行のときもうまくいかないのではないでしょうか? 解決方法としては以下のいずれかが考えられます。 1.変数をexportしてしまう。 2.シェルをbashに変更してwhileの部分も変更する。 while read LINE_STR do 省略 done < uniqData.txt 3.シェルをkshとかに変更。

mibusys
質問者

お礼

>パイプ以降がサブシェルで動作するからです。 おぉ。なるほど。非常に勉強になります。 方法としては#1の方が紹介してくださった方法で行いますが、 まだわかっていないことが多いので、こういう情報は非常に助かります。 ありがとうございます。

その他の回答 (2)

  • Toshi0230
  • ベストアンサー率51% (836/1635)
回答No.3

基本的にNo.1さんの回答で終わっちゃうんですが、少し補足。 データファイルがソートされていなくても % sort uniqData.txt | uniq -c でできますね。 出力形式が期待と違うでしょうけど、そこはawkなりperlなりで整形してください。

mibusys
質問者

お礼

整形は大丈夫です。 ありがとうございました。

  • t-okura
  • ベストアンサー率75% (253/335)
回答No.1

cat uniqData.txt | uniq -c

参考URL:
http://www.linux.or.jp/JM/html/gnumaniak/man1/uniq.1.html
mibusys
質問者

お礼

うわぁ。素人丸出しですね。ちょっと恥ずかしいです。 uniqは知っていたのですが、こんなオプションもあるんですね。 こちらの方法を利用して実装します。 大変助かりました。ありがとうございました。