http://www.perlmonks.org?node_id=1007640

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

Hi All, Am trying to print just directory and sub-directories names from the mentioned path. script reads directories recursively but it prints fullpath. I don't know how print just directory names or stored them in a array. Thanks for reading the post. Any help would be very greatful.

Main script :
#! /usr/bin/perl use strict; use warnings; my $base_dir = 'C:\Input'; my @to_visit = $base_dir; while (@to_visit) { my $dir = pop(@to_visit); opendir(my $dh, $dir); my $file; while(defined($file = readdir($dh))) { next if $file eq '.'; next if $file eq '..'; $file = "$dir/$file"; if (-d $file) { push(@to_visit, $file); print $file; print "\n"; } else { } } }
output now getting is :
C:Input/INT C:\Input/INT/CAD C:\Input/INT/CAD/MH C:\Input/INT/CAD/MH/COi C:\Input/INT/CAD/MH/Dit C:\Input/INT/CAD/MH/WMp
In the above output, i don't want to print/save last blank line. expecting output to be stored in some array:
INT CAD MH COi Dit WMp

Replies are listed 'Best First'.
Re: perl script to print just directory names
by toolic (Bishop) on Dec 06, 2012 at 20:25 UTC
Re: perl script to print just directory names
by blue_cowdawg (Monsignor) on Dec 06, 2012 at 20:33 UTC

    What extra line? Just tested your code on my system and don't see an extra line. There *is* however a "blank line" between the last line the script generates and the command line prompt but I think that's a function of the shell.

    Some more comments:

    Not sure why you are doing this:

    while(defined($file = readdir($dh)))
    when
    while($file = readdir($dh))
    should suffice.

    You do realize your array is going to be empty when your loop is done?


    Peter L. Berghold -- Unix Professional
    Peter -at- Berghold -dot- Net; AOL IM redcowdawg Yahoo IM: blue_cowdawg
Re: perl script to print just directory names
by davido (Cardinal) on Dec 07, 2012 at 00:41 UTC

    perldoc perlfaq5: How do I traverse a directory tree?

    Here's an example:

    use Data::Dumper; use File::Find; my $path = '/home'; my @dirs; { no warnings; # Squelch 'permission denied' warning, etc. find( sub { push @dirs, $File::Find::name if -d && ! /^\.\.?$/ }, $path ) } print Dumper \@dirs;

    Save yourself some time; spend a half-hour familiarizing yourself with the topics addressed in Perl's FAQ by reading perlfaq, and then refer back to it as needed.


    Dave

Re: perl script to print just directory names
by Kenosis (Priest) on Dec 06, 2012 at 23:01 UTC

    Find::File::Rule can assist with this. It is recursive:

    use strict; use warnings; use File::Find::Rule; my $base_dir = 'C:\Input'; my @dirs = File::Find::Rule->directory->in( $base_dir ); print $_, "\n" for @dirs;
Re: perl script to print just directory names
by 2teez (Vicar) on Dec 06, 2012 at 21:19 UTC

    Hi Vijaay81,
    As previously mentioned by toolic and others post before this. I also support using the module File::Find, which could reduce the number of lines of codes you write by half, if not more.
    Something like so:

    use strict; use warnings; use File::Find; find( sub { return if $_ eq '.' or $_ eq '..'; print $_, $/ if -d }, ' +.' ); #OR my @dir; find( sub { return if $_ eq '.' or $_ eq '..'; if (-d) { print $_, $/; # just to test push @dir, $_; # updated } }, '.' # this can be your "C:\Input" ); use DDP; p @dir;
    Update:
    Please, you would need module Data::Printer, installed for this line use DDP; p @dir; to work.
    Hope this helps.

    If you tell me, I'll forget.
    If you show me, I'll remember.
    if you involve me, I'll understand.
    --- Author unknown to me
Re: perl script to print just directory names
by Anonymous Monk on Dec 06, 2012 at 20:28 UTC
    findrule C:\Input --dir
    use [mod://File::Find::Rule]; my @dirs = find( directory =>in =>[ 'C:\ +Input' ]);
Re: perl script to print just directory names
by Vijay81 (Acolyte) on Dec 07, 2012 at 11:20 UTC

    Thanks Everyone. able to get just directory names using File::Basename. but can please someone show me how to store these basenames in some sort of array so that i can use them later part in the code.

    Main script:
    #! /usr/bin/perl use strict; use warnings; use File::Basename; use Data::Dumper; my $base_dir = 'C:Input/INT'; my @dir = $base_dir; my @dir_names; while (@dir) { my $dir = pop(@dir); opendir(my $dh, $dir); my $file; while($file = readdir($dh)) { next if $file eq '.'; next if $file eq '..'; $file = "$dir/$file"; if (-d $file) { push(@dir, $file); print basename($file); #@dir_names=basename($file); print "\n"; } else { } } }
    getting output as :
    CAD MH COi Dit WMp
    Instead of that i need to store the directory base names in array say @dir_names and print them one by one like $dir_names[0] = CAD $dir_names1 = MH $dir_names2 = COi .. .. ..

      "but can please someone show me how to store these basenames in some sort of array so that i can use them later part in the code."

      Consider reading and understanding the code you've posted, you already do this for a different array/value:

      push(@dir, $file);

      So rather than print the value of basename($file) to screen push the value of basename($file) into @dir_names.Read push, http://learn.perl.org.

      Update: slight clarification.

Re: perl script to print just directory names
by Vijay81 (Acolyte) on Dec 07, 2012 at 14:53 UTC
    Thank you all. Your suggestion worked.
Re: perl script to print just directory names
by Tommy (Chaplain) on Dec 09, 2012 at 21:53 UTC
    Use File::Util; my $f = File::Util->new(); my @dirs = $f->list_dir('C:\Input', qw( --dirs-only --recurse --with-p +aths ));
    --
    Tommy
    $ perl -MMIME::Base64 -e 'print decode_base64 "YWNlQHRvbW15YnV0bGVyLm1lCg=="'