2011-12-05 17 views
3

ディレクトリからファイルのリストを取得し、それぞれを開き、.zip拡張子を持つファイル名を含む行を検索するスクリプトを作成しています。次に、行のファイル名だけを取り除きたいと思います。ここに私のコードは次のとおりです。ファイル名を抽出する

foreach (@fnames) { 
    chomp ($_); 
    open FILE, '<', "$_"; 
    @archives = grep { /.+?\.zip/ } <FILE>; 

    foreach (@archives) { 
     if ($_ =~ /("|>)(.+?)("|<)/) { push @files, $2; } 
    } 
} 

私はからデータを引っ張っていたファイルは、二重引用符または角括弧のいずれかの間に.zipファイルのファイル名が含まれています。このコードは何も返さないが、私はファイル名がそこにあることを知っている。ターミナルでgrepを実行すると、それらのすべてを見ることができますが、Perlのgrepは私に何も与えていません。何か案は?

+0

。あなたは、 '@ archives'と' $ _'を2番目のループの中に投げ捨ててみましたか? – CanSpice

答えて

6

可能なもの:コード内のいくつかのエラーのあなたが 表示されていないので、

  • @fnamesは、空です。
  • open FILE, ...が失敗しましたが、openの戻り値 を確認していないため、警告メッセージは表示されません。したがって、あなたはそれについて知りません。あなたの入力に大文字を使用しています。たとえば、次のように入力します。 ZIP、および /i grepで大文字小文字を区別しないオプションを使用しないでください。最初に のBtwは .zipで始まる不要な文字列を期待しない限り、かなり役に立たない(つまり、文字が少なくとも1文字しかないことを確認する)。
  • 2番目のループ内のifステートメントは、最初に の一致を取得するだけです。また

  • あなたはopenと字句ファイルハンドルを使用する必要があります。
  • まだ実行していない場合は、厳密および警告を使用する必要があります。
  • my @archivesおよびmy @filesを適切なレキシカルスコープで使用すると、希望するデータを取得して保持するのに役立ちます。
  • $_ =~ /.../は、読みやすくするために/.../と書くことができます。 (IMO)。
  • あなたは本当に移行変数を必要としません。
  • ("|>)は、[">]という冗長な表現です。
  • grepは冗長処理です。あなたは、単に行うことができます:

while (<FILE>) { 
     push @files, /[">](.*\.zip)["<]/ig; 
} 

要するに:それは少しテストスクリプトで私の作品

my @files; 
foreach my $file (@fnames) { 
    chomp $file; 
    open my $fh, '<', $file or die $!; 
    while (<$fh>) { 
     push @files, /[">](.*\.zip)["<]/ig; 
    } 
} 
print "File names found: @files\n"; 
+0

それはすごくうまくいった!助けてくれてありがとう。私はautodieを使っていたので、ファイルハンドルを開いたときにdieを含めなかったのです。私は、(上記のように)問題は、@archives配列に値が設定されていないことだと思います。私はまだ正規表現を学んでいるので、私はすべてのヒントにまだ慣れていない。再度、感謝します! – stimko68

+0

@ stimko68よろしくお願いします! – TLP

0

あなたのスクリプトでは、何も出力していないので、配列の要素を変更するだけです。行をprintにするか、Tie::Fileを使用して、各ファイルに直接配列としてアクセスします。間違った

関連する問題