我有一个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
答案 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)检查某些内容是否为目录。