Perl: opendir, while readdir, next if, hash
Perl: opendir, while readdir, next if, hash
我有一个目录 $tmp
,其中包含名称语法为 .X*-lock
的文件以及其他普通文件和目录。
我将 $tmp
的内容与散列 table 中对应于 .X*-lock
不应删除的文件名的值进行比较。然后我希望脚本删除任何不在散列 table 中的 .X*-lock
文件。它不能删除普通文件(非“.”文件)、目录或 .
& ..
这是一些代码:
my %h = map { $_ => 1 } @locked_ports;
#open /tmp and find the .X*-lock files that DO NOT match locked_ports (NOT WORKING)
opendir (DIR, $tmp ) or die "Error in opening dir $tmp\n";
while ( (my $files = readdir(DIR)))
{
next if((-f $files) and (-d $files));
next if exists $h{$files};
#unlink($files) if !-d $files;
if (! -d $files){print "$files\n"};
}
closedir(DIR);
如您所见,现在我将 unlink
替换为 print
,因此我知道列出了正确的文件。
假设在我的 $tmp
目录中我有以下文件和目录:
./
../
cheese
.X0-lock
.X10-lock
.X11-unix/
.X1-lock
.X2-lock
.X3-lock
.X4-lock
.X5-lock
但哈希 table 中只有 .X1-lock
。因此我想 print/delete 所有其他 .X*-lock
文件,但不是 .X11-unix/
目录、cheese
文件或 .
& ..
使用上面的代码,它不会打印 .
或 ..
,这是好的,但它会打印 cheese
和 .X11-unix
。我怎样才能改变它,使它们不被打印出来?
(注意:这是一个梗 我被告知不要再在评论中提出更多问题,所以我提出了一个新问题。)
谢谢!
我可能会这样做:
opendir (my $dirhandle, $tmp) or die "Error in opening dir $tmp: $!";
while (my $file = readdir($dirhandle)) {
# skip directories and files in our hash
next if -d "$tmp/$file" || $h{$file};
# skip files that don't look like .X###-lock
next unless $file =~ /
\A # beginning of string
\. # a literal '.'
X # a literal 'X'
\d+ # 1 or more numeric digits
-lock # literal string '-lock'
\z # the end of the string
/x; # 'x' allows free whitespace and comments in regex
# unlink("$tmp/$file");
print "$file\n"
}
closedir($dirhandle);
如果您觉得它更具可读性,最后一个条件可以写成:
next if $file !~ /\A\.X\d+-lock\z/;
甚至:
if ($file =~ /\A\.X\d+-lock\z/) {
# unlink("$tmp/$file");
print "$file\n"
}
我有一个目录 $tmp
,其中包含名称语法为 .X*-lock
的文件以及其他普通文件和目录。
我将 $tmp
的内容与散列 table 中对应于 .X*-lock
不应删除的文件名的值进行比较。然后我希望脚本删除任何不在散列 table 中的 .X*-lock
文件。它不能删除普通文件(非“.”文件)、目录或 .
& ..
这是一些代码:
my %h = map { $_ => 1 } @locked_ports;
#open /tmp and find the .X*-lock files that DO NOT match locked_ports (NOT WORKING)
opendir (DIR, $tmp ) or die "Error in opening dir $tmp\n";
while ( (my $files = readdir(DIR)))
{
next if((-f $files) and (-d $files));
next if exists $h{$files};
#unlink($files) if !-d $files;
if (! -d $files){print "$files\n"};
}
closedir(DIR);
如您所见,现在我将 unlink
替换为 print
,因此我知道列出了正确的文件。
假设在我的 $tmp
目录中我有以下文件和目录:
./
../
cheese
.X0-lock
.X10-lock
.X11-unix/
.X1-lock
.X2-lock
.X3-lock
.X4-lock
.X5-lock
但哈希 table 中只有 .X1-lock
。因此我想 print/delete 所有其他 .X*-lock
文件,但不是 .X11-unix/
目录、cheese
文件或 .
& ..
使用上面的代码,它不会打印 .
或 ..
,这是好的,但它会打印 cheese
和 .X11-unix
。我怎样才能改变它,使它们不被打印出来?
(注意:这是一个梗
谢谢!
我可能会这样做:
opendir (my $dirhandle, $tmp) or die "Error in opening dir $tmp: $!";
while (my $file = readdir($dirhandle)) {
# skip directories and files in our hash
next if -d "$tmp/$file" || $h{$file};
# skip files that don't look like .X###-lock
next unless $file =~ /
\A # beginning of string
\. # a literal '.'
X # a literal 'X'
\d+ # 1 or more numeric digits
-lock # literal string '-lock'
\z # the end of the string
/x; # 'x' allows free whitespace and comments in regex
# unlink("$tmp/$file");
print "$file\n"
}
closedir($dirhandle);
如果您觉得它更具可读性,最后一个条件可以写成:
next if $file !~ /\A\.X\d+-lock\z/;
甚至:
if ($file =~ /\A\.X\d+-lock\z/) {
# unlink("$tmp/$file");
print "$file\n"
}