use warnings;
use strict;
my $dir = '/home/Enric/gfs-0.5.2016061400';
opendir my $dh, $dir or die "Can't open $dir: $!";
my $num_files = grep { -f "$dir/$_" } readdir($dh);
rewinddir($dh); # so that it can read the dir again
my $num_gfs = grep { /gfs./ } readdir($dh);
5条答案
按热度按时间3htmauhk1#
如果你只想计算它们,一旦你打开了一个目录进行阅读,你就可以操纵上下文,这样readdir就可以返回所有条目的列表,然后把它分配给一个标量。这给了你列表的长度,即。元素个数
字符串
构造
= () =
将列表上下文强加给readdir
,并将(表达式†)赋值给标量,从而获得该列表中元素的数量。 在perlsecret中查看。参见this page。当然,还有更清晰的方法,如下所示。
如果您想计算某些类型的文件,请首先通过grep传递文件列表,就像您所做的那样。由于
grep
在其输入上强加了列表上下文,因此readdir
返回所有文件的列表,并且在过滤之后,grep
本身返回列表。当你把它赋给一个标量时,你就得到了这个列表的长度(元素的数量),即。你的计数。例如,对于所有常规文件和/gfs./
文件型
(This仅是一个示例,使用
rewinddir
,以便它按原样工作。要真正从一个目录中获取两种文件,最好一次遍历一个条目,并在过程中对它们进行排序,或者将所有文件读入一个数组,然后处理该数组)readdir
返回的是空文件名,没有任何路径。* 因此,对于大多数通常对文件所做的操作,我们需要在其前面加上路径(除非您首先将chdir
添加到该目录)。这就是在上面的grep
块中所做的,以便-f
file test (-X)具有正确的文件名。如果您需要使用文件列表本身,请将其放入数组中,然后将其分配给标量
型
这里map为每个文件构建完整路径。如果不需要路径,请删除
map { }
。请注意,通常不需要在数组上正式使用scalar来获取计数,如型
相反,简单地将数组分配给标量,这是一种习惯用法(至少可以这么说)。
如果你是边读边处理文件,边数边走
型
这里
readdir
位于标量上下文中(因为它的输出被分配给标量),它遍历目录条目,每次返回一个。几个音符
/gfs./
--但如果这实际上意味着表示文字句点,那么应该用/gfs\./
替换readdir
如何返回裸文件名(无路径)的讨论在glob(或更好的File::Glob)中都不需要,它会返回完整路径型
这将返回路径为
$dir/filename
的文件列表。并不是说
opendir
+readdir
有什么问题。只是别忘了路。还有一种选择是使用库,比如Path::Tiny及其子方法。
†赋值
() = readdir $dh
本身也返回一个值,在这种情况下,that 整个表达式(赋值)被放置在标量上下文中。‡问题是Perl中的许多工具依赖于它们的操作并返回上下文,因此不能总是仅仅将列表分配给标量并期望获得列表的长度。
readdir
就是一个很好的例子,它返回列表上下文中所有条目的列表,但在标量上下文中只返回单个条目。§这里是另一个技巧
型
这里是一个匿名数组(引用)
[]
的构造函数,它将列表上下文强加给readdir
,而解引用@{ }
不关心上下文,只返回该arrayref的元素列表。所以我们可以把它赋值给一个标量,这样的scalar assignment返回该列表中元素的数量。kq4fsx7k2#
您有
@FILES
中的文件列表。所以你的问题变成了“我如何得到一个数组的长度?“这很简单,你只需在标量上下文中计算数组。字符串
或者,您可以使用
scalar()
函数消除不必要的标量变量。型
5cg8jx4n3#
尝试以下代码作为初学者(这是在Windows上,将包括
.
,..
和文件夹。如果只需要文件,可以过滤掉这些文件):字符串
smdncfj34#
我知道这不是在Perl中,但如果你需要一个快速的方法,只需在bash命令行中输入以下内容:
字符串
ls -1
提供目录中文件的列表,wc -l
提供行数。合并后,它们会给予你目录中的文件数量。或者,您可以从Perl调用bash(尽管您可能不应该这样做),使用
型
zour9fqk5#
作为zdim's answer的一个变体,假设您 * 没有 * 打开目录句柄。那样的话
字符串
可能更有用这与zdim的建议遵循相同的原理,但不需要先调用
opendir
。这将返回 * 不包含 * 的文件数,包括
.
和..
,至少在Linux上是这样。