Perl: opendir, while readdir, next if, hash

蓝咒 提交于 2019-12-25 03:42:45

问题


I have a directory $tmp that contains files with the name syntax .X*-lock as well as other plain files and directories.

I compare the contents of $tmp with values in a hash table corresponding to .X*-lock file names that should NOT be deleted. I then want the script to delete any, and ONLY .X*-lock files that aren't in the hash table. It cannot delete plain files (non "." files), directories, or . & ..

here's some code:

 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);

As you can see, for now I replaced unlink with print so I know the proper files are being listed.

Let's say in my $tmp dir I have the following files and directories:

./
../
cheese
.X0-lock
.X10-lock
.X11-unix/
.X1-lock
.X2-lock
.X3-lock
.X4-lock
.X5-lock

But only .X1-lock is in the hash table. Thus I want to print/delete all other .X*-lock files, but not the .X11-unix/ dir, the cheese file, or the . & ..

With the above code, it does not print . or .. which is good, but it does print cheese and .X11-unix. How can I change it so these are not printed as well?

(note: this is a stem off Perl: foreach line, split, modify the string, set to array. Opendir, next if files=modified string. Unlink files I was told to stop asking more questions in the comments so I made a new question.)

Thanks!


回答1:


I'd probably do something like this:

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);

If you find it more readable, that last conditional could be written as:

next if $file !~ /\A\.X\d+-lock\z/;

or even:

    if ($file =~ /\A\.X\d+-lock\z/) {
    #   unlink("$tmp/$file");
        print "$file\n"
    }


来源:https://stackoverflow.com/questions/29401277/perl-opendir-while-readdir-next-if-hash

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!