2009-10-02 99 views
9

我正在使用此代码来获取所有文件的特定目录的列表:如何从特定目录中获取具有特定扩展名的所有文件的列表?

opendir DIR, $dir or die "cannot open dir $dir: $!"; 
my @files= readdir DIR; 
closedir DIR; 

我怎么能修改此代码或追加的东西,以便它仅查找文本文件,只加载具有文件名前缀的数组?

实例目录内容:

. 
.. 
923847.txt 
98398523.txt 
198.txt 
deisi.jpg 
oisoifs.gif 
lksdjl.exe 

实例数组内容:

files[0]=923847 
files[1]=98398523 
files[2]=198 
+0

另外考虑为你的目录句柄使用一个词法变量:'opendir my $ dirh,$ dir_path or die“无法打开dir $ dir:$!”;' – 2009-10-02 16:30:37

回答

10
my @files = glob "$dir/*.txt"; 
for (0..$#files){ 
    $files[$_] =~ s/\.txt$//; 
} 
+0

任何想法如何将该目录重新排列呢?我的输出是/ dir/dir/dir/923847 ...我怎么才能得到923847? – CheeseConQueso 2009-10-02 15:50:37

+0

glob在这里添加额外的工作。请参阅http://stackoverflow.com/questions/1506801/what-reasons-are-there-to-prefer-glob-over-readdir-or-vice-versa-in-perl – 2009-10-02 16:09:59

5

它是足以改变一个行:

my @files= map{s/\.[^.]+$//;$_}grep {/\.txt$/} readdir DIR; 
2

得到公正的”。 txt“文件,您可以使用文件测试操作ator(-f:常规文件)和一个正则表达式。

my @files = grep { -f && /\.txt$/ } readdir $dir; 

否则,你可以看看只是文本文件,使用Perl的-T(ASCII文本文件测试操作)

my @files = grep { -T } readdir $dir; 
+0

-T用于测试您是否拥有“textfile” – reinierpost 2009-10-02 16:38:43

+0

好点;从运营商的perldoc页面(http://perldoc.perl.org/5.8.8/perlfunc.html),“-T \t文件是ASCII文本文件(启发式猜测)。”如果他正在寻找“.txt”文件,这将完全按照他未经猜测的方式进行。 – 2009-10-02 16:44:26

3

如果你可以使用Perl 5.10的新功能,这是怎么了我会写它。

use strict; 
use warnings; 
use 5.10.1; 
use autodie; # don't need to check the output of opendir now 

my $dir = "."; 

{ 
    opendir my($dirhandle), $dir; 
    for(readdir $dirhandle){ # sets $_ 
    when(-d $_){ next } # skip directories 
    when(/^[.]/){ next } # skip dot-files 

    when(/(.+)[.]txt$/){ say "text file: ", $1 } 
    default{ 
     say "other file: ", $_; 
    } 
    } 
    # $dirhandle is automatically closed here 
} 

或者,如果你有非常大的目录,你可以使用一个while循环。

{ 
    opendir my($dirhandle), $dir; 
    while(my $elem = readdir $dirhandle){ 
    given($elem){ # sets $_ 
     when(-d $_){ next } # skip directories 
     when(/^[.]/){ next } # skip dot-files 

     when(/(.+)[.]txt$/){ say "text file: ", $1 } 
     default{ 
     say "other file: ", $_; 
     } 
    } 
    } 
} 
1

只要使用此:

my @files = map {-f && s{\.txt\z}{} ? $_ :()} readdir DIR; 
1

这是我发现的最简单的方法(如人类可读)使用的glob功能:

# Store only TXT-files in the @files array using glob 
my @files = grep (-f ,<*.txt>); 
# Write them out 
foreach $file (@files) { 
    print "$file\n"; 
} 

此外,该“-f “确保只有实际文件(而不是目录)存储在数组中。

+0

为什么回滚编辑? 'foreach $ file'并不严格安全。如果你喜欢'foreach'来'for',为什么不'foreach我的$ file'? – 2015-07-27 14:22:50

+0

为什么编辑某人删除旧的东西,当你不知道为什么它张贴在第一个地方的原因?地狱我甚至不知道为什么我在三年前编写这段代码的原因,但由于我有一个测试事情的习惯,它可能工作得很好,并且可能有一个原因,我没有在严格声明。但是,这是否意味着我应该接受一个随机编辑,我是否还想花时间测试它?一定不行!这就是为什么我发现将它回滚更安全的原因。 – Kebman 2015-07-28 09:59:39

+0

要说清楚,我不是编辑它,我只是看到了编辑,并认为它改进了答案。您使用词法'@ files'然后是全局'$ file'就很奇怪。 – 2015-07-28 16:00:33

相关问题