Traverse a directory

Discussion in 'Perl Misc' started by weberw@adelphia.net, Jul 13, 2006.

  1. Guest

    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;
    , Jul 13, 2006
    #1
    1. Advertising

  2. Paul Lalli Guest

    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, Jul 13, 2006
    #2
    1. Advertising

  3. Guest

    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:
    > 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
    , Jul 13, 2006
    #3
  4. Paul Lalli Guest

    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
    Paul Lalli, Jul 13, 2006
    #4
  5. Dr.Ruud Guest

    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."
    Dr.Ruud, Jul 13, 2006
    #5
  6. <> 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
    Perl programming
    Fort Worth, Texas
    Tad McClellan, Jul 13, 2006
    #6
  7. DJ Stunks Guest

    Tad McClellan wrote:
    > <> wrote:
    > > return unless /[^.]/;

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


    lol

    stir the pot, Tad

    :p

    -jp
    DJ Stunks, Jul 14, 2006
    #7
  8. Guest

    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.
    , Jul 14, 2006
    #8
  9. Guest

    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
    , Jul 14, 2006
    #9
  10. <> 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
    Perl programming
    Fort Worth, Texas
    Tad McClellan, Jul 15, 2006
    #10
  11. Guest

    Tad- return if $File::Find::name =~ /folder 3/ gave the same results.
    It excluded the folder but did include the contents. Also, does anyone
    know how to print it so the out put would be formated like shown below?
    The file name needs to print out at the end of the direcotry name.

    Directory name1
    file1.xls
    file2.xls

    Directory name2
    file3.xls
    file4.xls
    file5.xls
    , Jul 15, 2006
    #11
  12. Guest

    Tad McClellan wrote:
    > <> 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
    > Perl programming
    > Fort Worth, Texas
    , Jul 15, 2006
    #12
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Thieum22
    Replies:
    1
    Views:
    681
    Joe Smith
    Aug 6, 2004
  2. Gary Wessle

    traverse directory with boost

    Gary Wessle, Aug 6, 2006, in forum: C++
    Replies:
    4
    Views:
    1,416
    Kai-Uwe Bux
    Aug 6, 2006
  3. Newbie

    How to Traverse a Directory

    Newbie, Sep 21, 2006, in forum: Ruby
    Replies:
    6
    Views:
    151
    Newbie
    Sep 21, 2006
  4. jay
    Replies:
    0
    Views:
    129
  5. glob and Traverse Directory

    , Jul 14, 2006, in forum: Perl Misc
    Replies:
    7
    Views:
    106
    Tad McClellan
    Jul 15, 2006
Loading...

Share This Page