如何解决打开/操作目录中所有文件的最有效方法是什么?
| 我需要在目录的所有文件上执行脚本(搜索)。这是有效的方法。我只是问哪个最好。 (我需要以下格式的文件名:parsedchpt31_4.txt) 地球:my $parse_corpus; #(for all options)
##glob (only if all files in same directory as script?):
my @files = glob(\"parsed\".\"*.txt\");
foreach my $file (@files) {
open($parse_corpus,\'<\',\"$file\") or die $!;
... all my code...
}
具有条件和条件的Readdir:
##readdir:
my $dir = \'.\';
opendir(DIR,$dir) or die $!;
while (my $file = readdir(DIR)) {
next unless (-f \"$dir/$file\"); ##Ensure it\'s a file
next unless ($file =~ m/^parsed.*\\.txt/); ##Ensure it\'s a parsed file
open($parse_corpus,\"$file\") or die \"Couldn\'t open directory $!\";
... all my code...
}
Readdir与foreach和grep:
##readdir+grep:
my $dir = \'.\';
opendir(DIR,$dir) or die $!;
foreach my $file (grep {/^parsed.*\\.txt/} readdir (DIR)) {
next unless (-f \"$dir/$file\"); ##Ensure it\'s a file
open($parse_corpus,\"$file\") or die \"Couldn\'t open directory $!\";
... all my code...
}
文件::查找:
##File::Find
my $dir = \".\"; ##current directory: could be (include quotes): \'/Users/jon/Desktop/...\'
my @files;
find(\\&open_file,$dir); ##built in function
sub open_file {
push @files,$File::Find::name if(/^parsed.*\\.txt/);
}
foreach my $file (@files) {
open($parse_corpus,\"$file\") or die $!;
...all my code...
}
还有另一种方法吗?将整个脚本包含在循环中是否很好?我不使用closedir可以吗?我正在将此传递给其他人,我不确定他们的文件在哪里(可能无法使用glob)
非常感谢,希望这是问这个问题的合适地点。
解决方法
最佳或最有效的方法取决于您的目的和更大的范围。在原始速度,代码简单性或其他方面,您说的最好吗?我对内存方面的考虑应该推动这一选择表示怀疑。目录中有多少个文件?
出于实用性考虑,“ 4”方法效果很好。在诉诸其他任何事情之前,我会先问是否有问题。
如果您能够使用其他模块,则另一种方法是让其他人担心肮脏的细节:
use File::Util qw();
my $fu = File::Util->new;
my @files = $fu->list_dir($dir,qw(--with-paths --files-only));
注意ѭ6执行递归搜索到所有子目录。很多时候,您不需要或不需要它。
我还要补充一点,我不喜欢您的两个“ 7”示例,因为它们融合了不同的功能:(1)获取文件名,(2)处理单个文件。我会将那些工作分开。
my $dir = \'.\';
opendir(my $dh,$dir) or die $!; # Use a lexical directory handle.
my @files =
grep { -f }
map { \"$dir/$_\" }
grep { /^parsed.*\\.txt$/ }
readdir($dh);
for my $file (@files){
...
}
, 我认为使用while
循环是更安全的答案。为什么?因为将所有文件名加载到数组中可能意味着大量的内存使用,并且使用逐行操作可以避免该问题。
我更喜欢7英镑而不是4英镑,但这可能更多是出于品味问题。
如果性能问题,可以说扩展名为.txt
的任何文件都不需要-f
检查。
, 我发现,使用完美的合作伙伴opendir
/readdir
和ѭ16my(我最喜欢的CPAN模块,非常适合跨平台)的递归目录遍历功能,可以使人们轻松而明确地操作目录中的任何内容,包括子目录(如果需要的话)(如果不需要,请省略递归)。
例子(一个简单的深ls
):
#!/usr/bin/env perl
use strict;
use warnings;
use File::chdir; #Provides special variable $CWD
# assign $CWD sets working directory
# can be local to a block
# evaluates/stringifies to absolute path
# other great features
walk_dir(shift);
sub do_something {
print shift . \"\\n\";
}
sub walk_dir {
my $dir = shift;
local $CWD = $dir;
opendir my $dh,$CWD; # lexical opendir,so no closedir needed
print \"In: $CWD\\n\";
while (my $entry = readdir $dh) {
next if ($entry =~ /^\\.+$/);
# other exclusion tests
if (-d $entry) {
walk_dir($entry);
} elsif (-f $entry) {
do_something($entry);
}
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。