saintex has asked for the wisdom of the Perl Monks concerning the following question:

SOLVED BY MYSELF:
opendir OF, $oldFolder or die "\nCannot open dir $oldFolder: $!\n"; while ( my $name=readdir OF) { next if $name =~ /^\./ ; next if -f "$oldFolder/$name"; print $name; print "\n"; } closedir OF;
---------------------------- Why this control fails?
while (my $name=readdir OF) { next if ( ($name =~ /^\./ )||(-f $name) ); #must print only directories print $name; print "\n"; }
the control on ".",".." is correct; but it is always a directory, also when $name is a file. In that context also "-d $name" returns true also when it is a file not directory

Replies are listed 'Best First'.
Re: check if it is a file or directory
by jwkrahn (Abbot) on Feb 26, 2010 at 14:58 UTC
    ---------------------------- Why this control fails?

    while (my $name=readdir OF) {
        next if ( ($name =~ /^\./ )||(-f $name) );

    That fails because you are testing the file name in the current directory instead of the $oldFolder directory.

    the control on ".",".." is correct

    Wrong: next if  $name =~ /^\./ will match any name that starts with '.', not just "." and "..".

      thank you for your answer... I understood that $name was the current directory and fixed by myself. Thank you for your precisation about . control. I'm not interesting in a correct control on hidden files, because in the directory of my interest there aren't, and I don't need to run that program outside that directory. But thank you for your answers
Re: check if it is a file or directory
by toolic (Bishop) on Feb 26, 2010 at 15:00 UTC
    If you don't need to use a while loop, you could get a list of all the directories using the File::Slurp read_dir function which by default ignores the special . and .. directories:
    use File::Slurp; my @dirs = grep { -d "$oldFolder/$_" } read_dir($oldFolder); print "$_\n" for @dirs;
    This approach is slightly different from yours in that it will not filter out other hidden directories, such as .foo.
      I tought to use a while, because my directory has really a lot of files, so with a while loop was easy to run that program again, also if it fails. If File::Slurp reads all files at once, and it pocesses them later, maybe my program crashes. Please let me know if Slurp acts in that way, or there is some control on directory reading. For that same reason I choose a "while" over any entries and not a "foreach" structure. For that I can understand, "foreach" read all the lines and then process it, but the "while" process all the lines, while reading. Thank you
        File::Slurp will read all directory contents (files and sub-directories) at once. Because your requirement is to process each file one at a time, do not use File::Slurp in this case.
Re: check if it is a file or directory
by Khen1950fx (Canon) on Feb 27, 2010 at 00:26 UTC
    I think that you're making things too hard on yourself. Just keep it simple. I tried this, and I double-checked. It's easier, and it is correct:
    #!/usr/bin/perl use strict; use warnings; chdir('/path/to/oldFolder'); my @files = <*>; foreach my $file (@files) { if ( -f $file ) { print $file . " file \n"; } if ( -d $file ) { print $file . " directory \n"; } }
      ... but your solution does not do what the OP wants:
      • Only print directory names (yours also prints file names).
      • Do not read all the names into an array at once -- just operate on each name, one at a time (yours stuffs all names into an array, then it loops through the array).
        But changing dir maybe a better solution for a more compact code. For example:
        $oldFolder='C:\Documents and Settings\user\Desktop'; opendir OF, $oldFolder or die "\nCannot open dir $old1Folder: $!\n"; chdir $oldFolder; while ( my $name=readdir OF) { next if $name =~ /^\./ or -f $name; # not interesting . o .. (or hidden files) neither in plain files print $name; } closedir OF;
        now -f test in oldFolder.