Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   Perl Misc (http://www.velocityreviews.com/forums/f67-perl-misc.html)
-   -   Traverse a directory (http://www.velocityreviews.com/forums/t898965-traverse-a-directory.html)

weberw@adelphia.net 07-13-2006 06:09 PM

Traverse a directory
 
I want to print out a listing of folders and their contents with
indentation. I don't want to print folder 3.

Example of output.

Folder 1
a.xls
b.xls
Folder 2
c.xls
d.xls


Here is my code. I want to keep the formatting above. How do you do
this as well as exclude folder 3?
#!C://Perl/bin/perl
use CGI ':standard';
use CGI::Carp 'fatalsToBrowser';
#use strict;
use warnings;
use File::Find;
my $file_count = 0;
my $dir_count = 0;


$title = "Find Files";
print header,
start_html($title),
h1($title);
find ( {
wanted => \&wanted}, 'C:/Documents and
Settings/weberw/Desktop/test');

printf "\nThere are %d files in %d directories.\n",
$file_count,
$dir_count;

sub wanted {


if (-d) {
return unless /[^.]/;
print "Directory Name is $File::Find::name\n";
print " \n";
$dir_count++;
}
elsif (-f _) {
print "File name is $File::Find::name\n";
$file_count++;
}
}




end_hmtl;


Paul Lalli 07-13-2006 06:53 PM

Re: Traverse a directory
 
weberw@adelphia.net wrote:
> I want to print out a listing of folders and their contents with
> indentation. I don't want to print folder 3.
>
> Example of output.
>
> Folder 1
> a.xls
> b.xls
> Folder 2
> c.xls
> d.xls
>
>
> Here is my code. I want to keep the formatting above. How do you do
> this as well as exclude folder 3?


Well, since this is a CGI script, why not just let the HTML formatting
happen for you, by using nested unordered lists? Then in your wanted
subroutine, if you have a directory, print the name followed by the
start of a new list. And after every subroutine, close the list.
#!/usr/bin/perl
use strict;
use warnings;
use File::Find;
use CGI qw/:standard/;
print header;
print start_html('Traversal');
my %skip_dir = map { $_ => 1 } ('Folder 3');

print "<ul>\n";
find({ wanted=>\&wanted, postprocess => \&post}, q{.});
print "</ul>\n";

sub wanted {
if ( -d and !/^\.\.?$/ and !$skip_dir{$_}) {
print "<li>$_\n<ul>\n";
}
if ( -f ) {
print "<li>$_</li>\n";
}
}

sub post {
print "</ul>\n</li>\n" unless $File::Find::dir eq q{.} or
$skip_dir{$File::Find::dir};
}
__END__


Paul Lalli


weberw@adelphia.net 07-13-2006 09:18 PM

Re: Traverse a directory
 
Thanks Paul! Can you explain a few things? Also, can you explain this
line?
if ( -d and !/^\.\.?$/ and !$skip_dir{$_}) {

what does the q{.}); do?
Paul Lalli wrote:
> weberw@adelphia.net wrote:
> > I want to print out a listing of folders and their contents with
> > indentation. I don't want to print folder 3.
> >
> > Example of output.
> >
> > Folder 1
> > a.xls
> > b.xls
> > Folder 2
> > c.xls
> > d.xls
> >
> >
> > Here is my code. I want to keep the formatting above. How do you do
> > this as well as exclude folder 3?

>
> Well, since this is a CGI script, why not just let the HTML formatting
> happen for you, by using nested unordered lists? Then in your wanted
> subroutine, if you have a directory, print the name followed by the
> start of a new list. And after every subroutine, close the list.
> #!/usr/bin/perl
> use strict;
> use warnings;
> use File::Find;
> use CGI qw/:standard/;
> print header;
> print start_html('Traversal');
> my %skip_dir = map { $_ => 1 } ('Folder 3');
>
> print "<ul>\n";
> find({ wanted=>\&wanted, postprocess => \&post}, q{.});
> print "</ul>\n";
>
> sub wanted {
> if ( -d and !/^\.\.?$/ and !$skip_dir{$_}) {
> print "<li>$_\n<ul>\n";
> }
> if ( -f ) {
> print "<li>$_</li>\n";
> }
> }
>
> sub post {
> print "</ul>\n</li>\n" unless $File::Find::dir eq q{.} or
> $skip_dir{$File::Find::dir};
> }
> __END__
>
>
> Paul Lalli



Paul Lalli 07-13-2006 09:25 PM

Re: Traverse a directory
 
weberw@adelphia.net wrote:
> Thanks Paul!


You're welcome. You can best show your appreciation by reading and
following the Posting Guidelines for this group. Specifically, please
do not top-post. Post your reply below the message you are replying
to, after trimming it leave only the relevant text.

> Can you explain a few things?


What few things, specifically, would you like explained? And have you
read the documentation for those things?

> Also, can you explain this line?
> if ( -d and !/^\.\.?$/ and !$skip_dir{$_}) {


-d is covered in `perldoc -f -d`. Regular expressions are covered in
`perldoc perlretut` (among others). Hashes are covered in `perldoc
perldata`.

This line says: "If $_ is a directory and if $_ is not either '.' or
'..' and if $_ does not have a true value inside the %skip_dir hash,
then ..."

> what does the q{.}); do?


the q, qq, qx, qr, and qw quoting operators are covered in `perldoc
perlop`
This is simply another way of writing a single-quoted string, such as
'.' When you use any of these "q" operators, you can choose any
non-alphanumeric character as your delimiter. Here I chose curly
braces. For very short strings, I will often use q{} or qq{} instead
of ' or ", as it can help increase readability (especially for the
empty string).

Paul Lalli


Dr.Ruud 07-13-2006 09:54 PM

Re: Traverse a directory
 
Paul Lalli schreef:
> weberw:


>> Also, can you explain this line?
>> if ( -d and !/^\.\.?$/ and !$skip_dir{$_}) {

>
> -d is covered in `perldoc -f -d`. Regular expressions are covered in
> `perldoc perlretut` (among others). Hashes are covered in `perldoc
> perldata`.
>
> This line says: "If $_ is a directory and if $_ is not either '.' or
> '..' and if $_ does not have a true value inside the %skip_dir hash,
> then ..."


<ignoring the Windows context>
I think that should be /\A\.\.?\z/, because $ can match before \n, and
qq/.\n/ and qq/..\n/ are possible names.
</ignoring>

--
Affijn, Ruud

"Gewoon is een tijger."



Tad McClellan 07-13-2006 10:33 PM

Re: Traverse a directory
 
weberw@adelphia.net <weberw@adelphia.net> wrote:
> I want to print out a listing of folders and their contents with
> indentation. I don't want to print folder 3.



> Here is my code.



It is not your code.

If you had written it, then you would already know how to exclude
directories (in fact the code already excludes some directories).


> sub wanted {
>
>
> if (-d) {
> return unless /[^.]/;



That is a pretty obfuscated way to eliminate the . and .. directories.

return if /folder 3/;


--
Tad McClellan SGML consulting
tadmc@augustmail.com Perl programming
Fort Worth, Texas

DJ Stunks 07-13-2006 11:02 PM

Re: Traverse a directory
 

Tad McClellan wrote:
> weberw@adelphia.net <weberw@adelphia.net> wrote:
> > return unless /[^.]/;

>
> That is a pretty obfuscated way to eliminate the . and .. directories.


lol

stir the pot, Tad

:p

-jp


weberw@adelphia.net 07-14-2006 09:56 PM

Re: Traverse a directory
 
Tad- return if /folder 3/; still included the files inside the
folder 3 so it didn't work. It did exclude folder 3 but the contents
of folder 3 were displayed.


weberw@adelphia.net 07-14-2006 10:03 PM

Re: Traverse a directory
 
Paul-thanks for the tips of posting guidelines. Wasn't aware of this
before. Anyway. I tried the skip dir that you mentioned and
unfortunately it does skip the folder but still includes the contents
of the folder.
Paul Lalli


Tad McClellan 07-14-2006 11:06 PM

Re: Traverse a directory
 
weberw@adelphia.net <weberw@adelphia.net> wrote:
> Tad- return if /folder 3/; still included the files inside the
> folder 3 so it didn't work. It did exclude folder 3 but the contents
> of folder 3 were displayed.



return if $File::Find::name =~ /folder 3/;


--
Tad McClellan SGML consulting
tadmc@augustmail.com Perl programming
Fort Worth, Texas


All times are GMT. The time now is 11:21 AM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.