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

A

Adam Petrie

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?
 
U

Umesh Nair

Adam said:
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);
 
D

David K. Wall

Adam Petrie said:
$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.
 
J

Jay Tilton

(e-mail address removed) (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 />";
: }
: }
 
T

Tad McClellan

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.
 
T

Tintin

Adam Petrie said:
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;
}
 
A

A. Sinan Unur

(e-mail address removed) (Adam Petrie) wrote in
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.
 
A

Adam Petrie

Tim Hammerquist said:
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!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,577
Members
45,054
Latest member
LucyCarper

Latest Threads

Top