• ベストアンサー

ファイルからある文字列の個数を数えたい

perl5でunixの"wc"や"grep -c"みたいに1つのファイルの中からある文字列の個数を カウントするスクリプトを作ろうとしています。 ファイルは256文字×10万行くらいのテキストで、 検索する文字列は15文字前後×40個(例えば「apple-000001」「lemon_orange」など)です。 どのようなスクリプトを組んだら効率よく各文字列をカウントできるのでしょうか? それよりwcやgrep -cを40回行った方が早いのでしょうか?

noname#41382
noname#41382
  • Perl
  • 回答数3
  • ありがとう数4

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

  • ベストアンサー
  • aton
  • ベストアンサー率47% (160/334)
回答No.3

最終的な速度については分かりませんが,Perl で効率良く実現しようというのであれば,配列(下の例では @pattern)に照合する文字列を入れておいて,ファイルから一行読むごとに, foreach $pattern (@pattern) { $count{$pattern} += /$pattern/g; #行の内容は $_ に入っていると仮定 } とかしてやればよいのではないでしょうか。 一行にパターンが必ず一回しか現れないのであれば,2行目は, $count{$pattern}++ if (/$pattern/); とかすることも可能でしょう。 上記コードでは,パターン照合回数は grep を使ったときと同じですが,ファイルI/Oの回数は 1/パターン数 で済みます。が,パターン照合の速度そのものは grep のほうが速いでしょうから,最終的にどちらが速いかはやってみないと分かりません。 ちなみに,Perl のパターンマッチング処理は,一般に sed と同等或いはより高速だと言われているので,sed を使う意味はあまりないと思います。

noname#41382
質問者

お礼

ご回答ありがとうございました。 まさにperlやりたかった内容です! grepと比較検討してみたいと思います。 #見た目的にはperl処理かな ^ ^;)

noname#41382
質問者

補足

1000行25パターンのテストデータでやってみたところ grep(25回)はperlの1.5倍処理時間がかかりました。 ということでperlで処理したいと思います。 ありがとうございました。

その他の回答 (2)

  • a-kuma
  • ベストアンサー率50% (1122/2211)
回答No.2

> また、systemコマンドでgrepを呼んだとすると、その結果をperlで処理するのはどうするのでしょうか? パイプを使います。perl は普段使わないので、怪しいのですが、こんな感じになるはず。 open IN, "grep なんとかかんとか |" or die "error\n"; while ( <IN> ) {   何か $_ を使った処理。例えば…   print; } close IN; > ファイルは1つです。その中で検索する文字列が40個あります。 ああ、そういうことなのね。ちょっと迷いますね。 sed で、一行一単語にばらしつつ、検索する文字列を含む行だけを抽出しておいて、その出力を perl で 処理してカウントして行くのが一番軽いかな?

noname#41382
質問者

お礼

さらなるご回答ありがとうございます。 パイプの使い方大変参考になりました。 sedのほうは、atonさんが回答していただいた処理と比較検討してみたいと思います。

  • a-kuma
  • ベストアンサー率50% (1122/2211)
回答No.1

直接の回答にはならないかもしれません。 > それよりwcやgrep -cを40回行った方が早いのでしょうか? wc や grep は、複数のファイルを一度に処理できますから、起動は一回だけで 済みます。 # 特定の単語を探すのであれば、wc には無理ですね。 perl もかなり早いんですが、(環境にもよりますが)grep なんかは、それなりに 速さを要求されてきて育ってきたプログラムですから、下手なスクリプトを書くよりは ずーっと早いです。 もし探す文字が、固定で構わない(つまり、正規表現を使わない)のであれば、 fgrep を使うのが一番早いんじゃないかと思います。

noname#41382
質問者

補足

回答ありがとうございます。 >grep は、複数のファイルを一度に処理できますから、起動は一回だけで済みます。 > ファイルは1つです。その中で検索する文字列が40個あります。 それぞれの個数を調べるにはやはり40回のgrepが必要ですか? あと、その前後の処理をperlで書いてしまっているので、perl上で処理できるように したいというのがあります。 また、systemコマンドでgrepを呼んだとすると、その結果をperlで処理するのはどうするのでしょうか? grepの結果をファイルに一度結果を出力する必要があるのでしょうか?

関連するQ&A

  • エクセルで文字列の個数を数える

    ある範囲のエクセルデータから決まった文字列の個数をカウントする関数の使い方が判れば教えてください。 例えば、A1からH200までのデータより、”リンゴ”という文字列が何個あるかカウントしたいのですが。 COUNTIF(A1:H200,"*リンゴ*")とすると”リンゴ”という文字列が含まれるセルの個数は出たのですが、”リンゴ”という文字列が複数含まれるセルもあるので、”リンゴ”という文字列の個数とは 一致しないようなのです。 どなたか、よろしくお願いします。

  • 文字列数の高速なカウント

    あるファイルに入っている文字列をカウントする早い方法を探しています。 grep -c "sample"やawk '{if($1 ="sample") print}' |wc などを試していますが、巨大なファイルのためすごく時間がかかっています。 他に何か早く計算できる方法はないでしょうか?

  • 別ファイルの文字列の個数をカウントするには?

    下記のようにA列に文字列が入っているBファイルがあります。 Cファイルで上記A列の「1」を含むセルの個数を数えるために COUNTIFを使っているのですが 一度保存し開くと「#VALUE!」が表示されてしまいます。 どのようにしたらうまく行くのでしょう? ちなみに、Bファイルはいじれません。 また「1」以外の数字の個数も数える予定です。 今は【=COUNTIF(範囲,”*文字列*”)】という計算式を入れています。 A列 1 1.4(この.は小数点ではありません。) 3 2 2.3.4

  • 複数列の中の文字列の検索、個数抽出

    どなたかお力をお貸しください。。 エクセル2003を使用しています。    A列 B  C  D 1  あ  う     あ 2  い  お  か  か 3  う        う 4  え     き  く 5  お  い  う  け Dの文字列のなかでA~C列の中に重複している文字が何個あるかを出したいです。 この場合D列は「あ、か、う、く、け」なので、A~C列にある「あ、か、う」が重複しているので、3個と出したいです。 もしくは重複していない「く、け」で2個と出したいです。 MATCH関数を使うと出来そうなのですが、MATCH関数だと配列の概念がなさそうなので、どうしたものかと。 条件として、 ・一つのセルで関数を使用して出す。 ・マクロ、計算用のセルはできたら使用しない。 ・空白セルもあり、文字列の完全一致のみ個数としてカウント。 ・列の数はだんだん増えてくるので、列数は増えても大丈夫なやり方の方がいいです。 COUNTIFで重複個数を出すと、「う」が複数回出てくるので、重複の個数が増えてしまい困っています。 もしかしたら不可能かもしれませんが、どなたかお知恵をお貸しください。 よろしくお願いいたします。

  • 指定文字の同じ行2列、3列目の文字入力の個数

    B列3~12行に文字が入力されており指定文字Bの行の2列目に文字が入力されていればその個数をC14にまた3列目に文字入力個数5個をD14に入力したいのですがどなたか関数が解る方宜しくお願いします。Excel2013です。

  • Bシェル 文字列に含まれる特定文字のカウント

    文字列の中に特定の文字が何個含まれているのかを知りたいです。wcやgrep を使ってみましたが、うまくいきません。教えてください。 例えば「123456789abc1defg0123456789」 の中に「1」は3個含まれているってのを調べたいです。

  • 文字列検索(grepのようなもの)のCソースコード知りませんか?

    Cソースコードを探しています。文字列検索用のコードです。UNIXのgrepみたなことができればと思います。 ご存知でしたら教えてください。お願いします。

  • 複数の文字列を検索

    あるログファイルの文字列を取得して。検索でヒットした文字列行 を返すスクリプトを作成しております。 検索:"OK"    日付 対象行 : OK! Tue Jul 19 文字列"OK"は普通に # grep "OK" ログファイルPath で検索できますが、 文字列と日付を両方引っ掛ける場合は・・・ grep -e "OK" -e env LANG=c date -u +"%a %b $d" ログファイルPath 当然コマンドエラーになります。 dateコマンドから日付を取得して、grepにて引っ掛ける方法を知りたいので すが、お分かりになる方、ご教授お願い致します。

  • 特定の文字列を含む行だけ削除する方法?

    いつもお世話になっています。 Unixであるテキストファイルから、 特定の文字列を含む行(レコード)だけを 削除する方法を教えてください。 現在、grepを使って、いろいろ試しているのですが、 正規表現で、 ”***”を含まない行(レコード)だけを 切り出すとう正規表現の説明が見あたりません。 "^**"は、**以外の文字を検索できるようですが、 文字列に対しては、使えません。 grep以外の方法でも良いのですが、 なるべくシンプルにできる方法がありましたら 教えてください。 宜敷お願いします。

  • エクセルでの検索条件にあった文字列の個数計算。

    お世話になります。 エクセルで、文字列の個数を数えたいのですが、 やり方を教えてください。。。 例えば、 リンゴ メロン オレンジ があったとして、 一つ目は、リンゴのみの数。 二つ目はリンゴとオレンジの数、という具合に条件を変えて数えさせたいのですが。。。 よろしくお願いします<(_ _)>