我想获得没有“。”的子目录列表(在第一级)。和“...”在例如dir“/ var /”。我有这个perl脚本,但它不起作用:
#!/bin/perl
opendir(my $DH, $ARGV[0]) || die "$!\n";
my @dirs
= grep {
-d "$_" &&
/[^.]/
} readdir($DH);
@dirs = sort(@dirs);
closedir $DH;
print "@dirs\n";
输出是:
$ ./_copyplg.pl /var
<nothing>
/ var
列表$ ls -1a /var
.
..
adm
cache
crash
db
empty
lib
local
lock
log
lost+found
mail
run
spool
tmp
var
www
请在哪里弄错了?
答案 0 :(得分:2)
您说的是&#34; $_
是一个目录,$_
至少包含{{1>}中任何字符的一个&#34; 1}}阻止。您需要转义正则表达式中的grep
。
如果您只是否定匹配,则不需要字符类.
。放置字符串锚的开头也是有意义的,并确保只获得[]
和.
,因为您可能希望以后允许包含点的目录打开,或者甚至以点..
开头,这是有效的。
/var/.foo/
现在它将与my $dir = $ARGV[0];
my @dirs = grep { ! /^\.\.?\z/ && -d "$dir/$_" } readdir $DH;
和.
匹配,但不会有任何其他内容,并且会否定这些内容。
请注意您需要将目录添加到..
检查,因为-d
仅返回文件名,而不是其完整路径。因为你没有从readdir
启动程序,而且你也没有在那里切换你当前的目录,所以这是必需的。
如果您计划对readdir的返回值进行文件测试, 你最好在前面有问题的目录。否则,因为我们 那里没有chdir,它会测试错误的文件。
查看perldoc on readdir
,因为其中包含有关如何过滤$dir
和.
的实际示例以及有关文件名的警告。
您的Perl程序中应该..
和use strict
。在这种情况下,它不会帮助你找到问题,但它会让你的生活更轻松。