2016-10-24 10 views
0

コマンドラインファイルから取り出し、すべてのファイルから単語の出現数を出力する小さなプログラムを作成しようとしています。最初の部分は、単語の出現の数を見つける、うまくいくようです。Perl:単語が出現するファイルを出力する

しかし、私は第2の部分、つまりどのファイル(ファイル名)に単語があるかを見つけることに苦労しています。私は単語を格納する配列を使用することを考えていますが、これが最善の方法か、それとも最善の方法か分かりません。 これは、これまで私が持っているコードで、単語が与えられたファイル(複数可)に発生した回数をカウント部分のために働くようだ:

use strict; 
use warnings; 

my %count; 

while (<>) { 

    my $casefoldstr = lc $_; 

    foreach my $str ($casefoldstr =~ /\w+/g) { 
    $count{$str}++; 
    } 
} 

foreach my $str (sort keys %count) { 
    printf "$str $count{$str}:\n"; 
} 
+2

コードに字下げを修正しました。一見無作為にインデントされたコードを何人が作成しようとしているのか、私は絶えず驚いています! –

+0

'perltidy -pbp' ftw! – Sobrique

+1

あなたが望むような出力を見せてくれれば多分助けになるでしょう。 – Borodin

答えて

2

は、合理的なようだ - そして、あなたは常にできます配列に格納されている最後の値をチェックするだけです。それ以外の場合は、ハッシュを使用します。

#!/usr/bin/perl 
use warnings; 
use strict; 

my %count; 
my %in_file; 
while (<>) { 
    my $casefoldstr = lc; 
    for my $str ($casefoldstr =~ /\w+/g) { 
     ++$count{$str}; 
     push @{ $in_file{$str} }, $ARGV 
      unless ref $in_file{$str} && $in_file{$str}[-1] eq $ARGV; 
    } 
} 

foreach my $str (sort keys %count) { 
    printf "$str $count{$str}: @{ $in_file{$str} }\n"; 
} 
4

ファイル名が$ARGVを介してアクセス可能です。

あなたはキーとして、ファイル名や単語とネストされたハッシュを構築するためにこれを使用することができます:あなたは複数回任意のファイルを訪問していない場合は、配列を使用して

use strict; 
use warnings; 
use List::Util 'sum'; 

while (<>) { 
    $count{$word}{$ARGV}++ for map +lc, /\w+/g; 
} 

foreach my $word (keys %count) { 

    my @files = keys %$word; # All files containing lc $word 
    print "Total word count for '$word': ", sum(@{ $count{$word} }{@files}), "\n"; 

    for my $file (@files) { 
     print "$count{$word}{$file} counts of '$word' detected in '$file'\n"; 
    } 
} 
+0

同じファイルが2回提供される場合、出力はどうなるでしょうか? – reinierpost

+0

@reinierpost同じファイルが2回提供された場合、そのファイルの単語数は2倍になります。その特定の(そして眉を上げる)シナリオは、 'while'ループに達する前に' @ ARGV'を前処理することによって和らげることができます: 'use List :: Util qw(sum uniq); BEGIN {@ARGV = uniq @ARGV} ' – Zaid

+0

または[' eof'](http://perldoc.perl.org/functions/eof.html)でハッシュを印刷して消去します。 – reinierpost

関連する問題