我有一个目录,其中包含大约5000个2,400大小的.txt文件。
我只想要该目录中的一个文件名;顺序无所谓。
将处理和删除该文件。
这不是脚本工作目录。
目的是:
我的粗略尝试不仅检查.txt文件,还必须为一个文件名获取所有~5000个文件名。我也可能打电话给太多模块?
Verify_Empty
sub旨在验证是否有一个目录,其中有文件但是,我的尝试失败了,所以我在这里寻求帮助。
#!/usr/bin/perl -w
use strict;
use warnings;
use CGI;
use CGI ':standard';
print CGI::header();
use CGI::Carp qw(fatalsToBrowser warningsToBrowser);
###
use vars qw(@Files $TheFile $PathToFile);
my $ListFolder = CGI::param('openthisfolder');
Get_File($ListFolder);
###
sub Get_File{
$ListFolder = shift;
unless (Verify_Empty($ListFolder)) {
opendir(DIR,$ListFolder);
@Files = grep { $_ ne '.' && $_ ne '..' } readdir(DIR);
closedir(DIR);
foreach(@Files){
$TheFile = $_;
}
#### This is where I go off to process and unlink file (sub not here) ####
$PathToFile = $ListFolder.'/'.$TheFile;
OpenFileReadPrepare($PathToFile);
#### After unlinked, the OpenFileReadPrepare sub loops back to this script.
}
else {
print qq~No more files to process~;
exit;
}
exit;
}
####
sub Verify_Empty {
$ListFolder = shift;
opendir(DIR, $ListFolder) or die "Not a directory";
return scalar(grep { $_ ne "." && $_ ne ".." } readdir(DIR)) == 0;
closedir(DIR);
}
显然我对此非常陌生。这种方法看起来很“饥饿”? 抓取一个文件名并处理它似乎很多! 指导会很棒!
编辑 - 最新尝试
my $dir = '..';
my @files = glob "$dir/*.txt";
for (0..$#files){
$files[$_] =~ s/\.txt$//;
}
my $PathAndFile =$files[0].'.txt';
print qq~$PathAndFile~;
这“工作”,但它仍然获取所有文件名。到目前为止,这里没有一个例子对我有用。我想今天我会忍受这个,直到我弄明白。也许我会重温一下,看看是否有人想出更好的东西。
答案 0 :(得分:4)
你可以在while循环中使用readdir循环。这样,readdir将不会返回所有文件,但当时只返回一个文件,
# opendir(DIR, ...);
my $first_file = "";
while (my $file = readdir(DIR)) {
next if $file eq "." or $file eq "..";
$first_file = $file;
last;
}
print "$first_file\n"; # first file in directory
答案 1 :(得分:4)
您在列表上下文中调用readdir
,它返回所有目录条目。在标量上下文中调用它:
my $file;
while( my $entry = readdir DIR ) {
$file = $entry, last if $entry =~ /\.txt$/;
}
if ( defined $file ) {
print "found $file\n";
# process....
}
另外,你读了两次目录;一旦看到它是否有任何条目,然后处理它。你真的不需要看看目录是否为空;你可以在处理循环中免费获得它。
答案 2 :(得分:2)
除非我大错特错,你想要的只是迭代一个目录中的文件,所有这些关于“第一个或最后一个”和“顺序无关紧要”并删除文件只是混淆了如何做到这一点。
所以,让我以一种非常简单的方式为您介绍它,看看它是否真的符合您的要求:
my $directory = "somedir";
for my $file (<$directory/*.txt>) {
# do stuff with the files
}
glob
将与* nix shell相同,它将列出具有.txt
扩展名的文件。如果你想对循环内的文件做进一步的测试,那就完全没问了。
缺点是将5000个文件名保留在内存中,并且如果处理此文件列表需要时间,则可能会与同时访问这些文件的其他进程冲突。
另一种方法是在while循环中简单地用readdir
读取文件,例如他的答案中提到的mpapec。好处是每次读取新文件名时,文件都会在那里。此外,您不必在内存中保留大量文件。