f



Getting all directories/files from current directory and using -d flag for the directories

Hi guys/gals,

I'm pretty new to Perl, so please keep that in mind. :)

It looks like File::Find goes through all the subdirectories of the
current directory, which isn't what I want.  I just want all the
contents of the current directory.

On doing some research, many people have recommended doing something
like the following:
-----------
$home_dir = ''; #changed to protect the innocent :)

opendir(DIR,$home_dir) or die "Can't open the current directory:
$home_dir $!\n";

# read file/directory names in that directory into @names
@names = readdir(DIR) or die "Unable to read current dir:$!\n";

closedir(DIR);

foreach $name (@names) {
   next if ($name eq ".");   # skip the current directory entry
   next if ($name eq "..");  # skip the parent  directory entry

   if (-d $name){            # is this a directory?
      print "found a directory: $name<br />";
   }
   else {
     print "found a file: $name <br />";
  }
}
-----------
However, the -d doesn't seem to be working right.  Most of the output
comes from the else part when it should be showing many directories
instead.

What is going on?  Any other solutions?
0
10/8/2004 8:05:10 PM
comp.lang.perl.misc 33233 articles. 2 followers. brian (1246) is leader. Post Follow

9 Replies
1059 Views

Similar Articles

[PageSpeed] 42

Adam Petrie wrote:
> Hi guys/gals,
> 
> I'm pretty new to Perl, so please keep that in mind. :)
> 
> It looks like File::Find goes through all the subdirectories of the
> current directory, which isn't what I want.  I just want all the
> contents of the current directory.
> 

You might want to use the very convenient File::Finder module from CPAN.

use File::Finder;
my @array = File::Finder->type('f')->in($dir_loc);

0
Umesh
10/8/2004 8:37:57 PM
Adam Petrie <adam.petrie@walgreens.com> wrote:

> $home_dir = ''; #changed to protect the innocent :)
> 
> opendir(DIR,$home_dir) or die "Can't open the current directory:
> $home_dir $!\n";
> 
> # read file/directory names in that directory into @names
> @names = readdir(DIR) or die "Unable to read current dir:$!\n";
> 
> closedir(DIR);
> 
> foreach $name (@names) {
>    next if ($name eq ".");   # skip the current directory entry
>    next if ($name eq "..");  # skip the parent  directory entry
> 
>    if (-d $name){            # is this a directory?
>       print "found a directory: $name<br />";
>   }
>    else {
>      print "found a file: $name <br />";
>  }
>}
> -----------
> However, the -d doesn't seem to be working right.  Most of the
> output comes from the else part when it should be showing many
> directories instead.
> 
> What is going on?  Any other solutions?

Maybe your program's default directory while executing is not what 
you think it is? The chdir function could be useful in that case.
0
David
10/8/2004 8:55:17 PM
Adam Petrie <adam.petrie@walgreens.com> wrote:
> On doing some research, many people have recommended doing something
> like the following:
> -----------
> $home_dir = ''; #changed to protect the innocent :)
> 
> opendir(DIR,$home_dir) or die "Can't open the current directory:
> $home_dir $!\n";
> 
> # read file/directory names in that directory into @names
> @names = readdir(DIR) or die "Unable to read current dir:$!\n";
> 
> closedir(DIR);
> 
> foreach $name (@names) {
>    next if ($name eq ".");   # skip the current directory entry
>    next if ($name eq "..");  # skip the parent  directory entry
> 
>    if (-d $name){            # is this a directory?
>       print "found a directory: $name<br />";
>    }
>    else {
>      print "found a file: $name <br />";
>   }
> }
> -----------
> However, the -d doesn't seem to be working right.  Most of the output
> comes from the else part when it should be showing many directories
> instead.

Assuming the directory structure:

    /data           <- directory where you're looking for file/dirs
    /bin            <- directory where your script is located
    /other          <- another directory where your script is called *from*

and $home_dir is set to "/data", then the directories and files returned
by readdir() will be in /data.  However, when you do the -d test, the
test is performed relative to the directory from which the script is
executed ("/other") and so is checking whether /other/somefile is
a directory, rather than /data/somefile, as you intend.

Just prefix $user_dir onto $name and test that way:

: foreach $name (@names) {
:    next if ($name eq ".");   # skip the current directory entry
:    next if ($name eq "..");  # skip the parent  directory entry
: 
:    $name = "$home_dir/$name";
:    if (-d $name){            # is this a directory?
:       print "found a directory: $name<br />";
:    }
:    else {
:      print "found a file: $name <br />";
:   }
: }

Oh, and remember to use strict;

HTH,
Tim Hammerquist
0
Tim
10/8/2004 10:07:55 PM
adam.petrie@walgreens.com (Adam Petrie) wrote:

: $home_dir = ''; #changed to protect the innocent :)
: 
: opendir(DIR,$home_dir) or die "Can't open the current directory:
: $home_dir $!\n";
: 
: # read file/directory names in that directory into @names
: @names = readdir(DIR) or die "Unable to read current dir:$!\n";
: 
: closedir(DIR);
: 
: foreach $name (@names) {
:    next if ($name eq ".");   # skip the current directory entry
:    next if ($name eq "..");  # skip the parent  directory entry
: 
:    if (-d $name){            # is this a directory?

Better question:  Does $name contain the path to the directory that was
opened and readdir()ed earlier?

Answer:  Nope.

    use File::Spec::Functions qw(catfile);
    if (-d catfile($home_dir, $name) ) {

:       print "found a directory: $name<br />";
:    }
:    else {
:      print "found a file: $name <br />";
:   }
: }

0
tiltonj
10/8/2004 10:09:54 PM
Adam Petrie <adam.petrie@walgreens.com> wrote:


> I'm pretty new to Perl, so please keep that in mind. :)


The docs that come with perl are a great resource.

You should become accustomed to looking at them as a *first*
step in troubleshooting.


> opendir(DIR,$home_dir) or die "Can't open the current directory:
> $home_dir $!\n";
> 
> # read file/directory names in that directory into @names
> @names = readdir(DIR) or die "Unable to read current dir:$!\n";


   perldoc -f readdir

anticipates the very problem you are having.

Your problem could have been solved in about 20 seconds by
using the docs...


>    if (-d $name){            # is this a directory?

       If you're planning to filetest the return values out of a
       "readdir", you'd better prepend the directory in question.
       Otherwise, because we didn't "chdir" there, it would have been
       testing the wrong file.


> What is going on?  


You are using a function without having read its documentation.

This is the programming equivalent of signing a contract without
reading it first. Very dangerous!


> Any other solutions?


Read the documentation for the functions that you use.


-- 
    Tad McClellan                          SGML consulting
    tadmc@augustmail.com                   Perl programming
    Fort Worth, Texas
0
Tad
10/8/2004 11:41:27 PM
"Adam Petrie" <adam.petrie@walgreens.com> wrote in message 
news:9d42ced3.0410081205.7c9fec80@posting.google.com...
> Hi guys/gals,
>
> I'm pretty new to Perl, so please keep that in mind. :)
>
> It looks like File::Find goes through all the subdirectories of the
> current directory, which isn't what I want.  I just want all the
> contents of the current directory.

in that case, just do

#!/usr/bin/perl
use strict;

foreach (</path/to/dir/*>) {
  print "Directory: $_\n" if -d;
  print "File: $_\n" if -f;
}


0
Tintin
10/9/2004 1:10:55 AM
adam.petrie@walgreens.com (Adam Petrie) wrote in 
news:9d42ced3.0410081205.7c9fec80@posting.google.com:

> However, the -d doesn't seem to be working right.  Most of the output
> comes from the else part when it should be showing many directories
> instead.
> 
> What is going on?  Any other solutions?

It is always a good idea to actually read the documentation for the 
functions you are using:

perldoc -f readdir

Sinan.
0
A
10/9/2004 3:14:40 AM
On 8 Oct 2004 13:05:10 -0700, adam.petrie@walgreens.com (Adam Petrie)
wrote:

>opendir(DIR,$home_dir) or die "Can't open the current directory:
[snip]
>   if (-d $name){            # is this a directory?


How strange! This very same question was asked here a few days ago,
see:

<41648726$0$1274$5a62ac22@per-qv1-newsreader-01.iinet.net.au>

and followups.


Michele
-- 
{$_=pack'B8'x25,unpack'A8'x32,$a^=sub{pop^pop}->(map substr
(($a||=join'',map--$|x$_,(unpack'w',unpack'u','G^<R<Y]*YB='
..'KYU;*EVH[.FHF2W+#"\Z*5TI/ER<Z`S(G.DZZ9OX0Z')=~/./g)x2,$_,
256),7,249);s/[^\w,]/ /g;$ \=/^J/?$/:"\r";print,redo}#JAPH,
0
Michele
10/9/2004 10:49:11 AM
Tim Hammerquist <tim@vegeta.ath.cx> wrote in message news:<slrncme3o7.pg6.tim@vegeta.saiyix>...
> Assuming the directory structure:
> 
>     /data           <- directory where you're looking for file/dirs
>     /bin            <- directory where your script is located
>     /other          <- another directory where your script is called *from*
> 
> and $home_dir is set to "/data", then the directories and files returned
> by readdir() will be in /data.  However, when you do the -d test, the
> test is performed relative to the directory from which the script is
> executed ("/other") and so is checking whether /other/somefile is
> a directory, rather than /data/somefile, as you intend.
> 
> Just prefix $user_dir onto $name and test that way:
> 
> : foreach $name (@names) {
> :    next if ($name eq ".");   # skip the current directory entry
> :    next if ($name eq "..");  # skip the parent  directory entry
> : 
> :    $name = "$home_dir/$name";
> :    if (-d $name){            # is this a directory?
> :       print "found a directory: $name<br />";
> :    }
> :    else {
> :      print "found a file: $name <br />";
> :   }
> : }
> 
> Oh, and remember to use strict;
> 
> HTH,
> Tim Hammerquist

Thanks Tim,

I wasn't adding the prefix for the full path.  It works now!
0
adam
10/11/2004 1:28:19 PM
Reply: