Perl中的递归打开文件

时间:2013-05-22 10:09:51

标签: perl file recursion

我有一个Perl脚本来计算表达式在文件中出现的次数,在这种特殊情况下它会计算'<'之间找到的所有内容。和'>'因为我希望它解析.xml文件。

脚本:

#usr/bin/perl

sub by_count {
   $count{$b} <=> $count{$a};
}

open(INPUT, "<[Content_Types].xml");
open(OUTPUT, ">output");
$bucket = qw/./;


while(<INPUT>){
   @words = split(/\</);

   foreach $word (@words){
            if($word=~/($bucket*>)/io){

      #print OUTPUT "$word";
      #print OUTPUT "\n\n";
      $count{$1}++;}

   }
}
foreach $word (sort by_count keys %count) {

   print OUTPUT "<$word occurs $count{$word} times\n\n";

}

close INPUT;
close OUTPUT;

输出

<Default Extension="xlsx" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"/> occurs 1 times

<Default Extension="png" ContentType="image/png"/> occurs 1 times

<Override PartName="/word/theme/theme1.xml" ContentType="application/vnd.openxmlformats-officedocument.theme+xml"/> occurs 1 times

问题

我想递归地做。我有一个内部有多个子目录的目录,每个子文件夹里面都有一个[Content_Types] .xml文件。有关如何解析主目录中找到的具有该名称的每个文件的任何建议吗?

示例图:

>Directory
  >Directory1
    >[Content_Types].xml
  >Directory2
    >[Content_Types].xml
  >Directory3
    >[Content_Types].xml
  .
  .
  .

  >Directory100
    >[Content_Types].xml

2 个答案:

答案 0 :(得分:5)

一种方法是使用模块Find::File,它将遍历所有子目录以找到你告诉它的内容。它会是这样的:

#!/usr/bin/env perl

use warnings;
use strict;
use File::Find;

find( \&wanted, shift );

sub wanted {
        return unless -f $_ && m/\[Content_Types\]\.xml/;
        open my $fh, '<', $_ or do {
                warn qq|WARNING: Could not open $File::Find::name\n|;
                return;
        };  
        open my $ofh, '>', 'output';
        my $bucket = qw/./;

        while ( <$fh> ) { 
                ## ... your code here ...
        }   

        ## ... your code here ...
}

将您希望搜索开始的目录作为参数:

perl script.pl .

答案 1 :(得分:2)

没有必要递归地执行此操作。它迭代工作得非常好。

定义一堆目录:

my @directories;

然后将开始目录推入列表:

push(@directories, "startdirectory");

最后,作为一个循环,你可以这样做:

while(my $dir=shift(@directories))

然后,对于每个遍历的目录,将所有找到的子目录推送到列表中。之后,查找文件并根据需要解析它们(即添加上面列出的代码)。

提示:您可以使用(-d myfile)检查某些内容是否为目录。