Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW

Read Directory

by Nansh (Acolyte)
on May 26, 2017 at 06:16 UTC ( [id://1191269]=perlquestion: print w/replies, xml ) Need Help??

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

Hi, My code is like this
#!usr/bin/perl $path='/home/something/something/something'; opendir(DIR,$path) or die"couldnt open the directory\n"; while(readdir(DIR)) { if(-d BUS) { opendir(VEH,"BUS") or die"couldnt open the directory\n"; while(readdir(VEH)) { print "$_\n"; } } }

In this path $path='/home/something/something/something'; many directories are there. say BUS, CAR, LORRY If the directory BUS exists then read that directory and display the files in that directory I am trying but i am not able to get that


Replies are listed 'Best First'.
Re: Read Directory
by shmem (Chancellor) on May 26, 2017 at 07:05 UTC

    Had you used strict, the perl compiler would have tould you the error. This

    if(-d BUS)

    doesn't do what you want. BUS is a bareword here which is just a symbol that can be used e.g. as a directory handle (not under strict, though). Then, even if it was a directory entry (which it isn't), you need to prepend $path to correctly name it's location.You can use either of

    if ( $_ eq "BUS" and -d "$path/$_" ) # string equality test if ( /^BUS$/ && -d "$path/$_" ) # pattern match on $_

    But it is not necessary to read the contents of a directory to test for existence of a directory within whose name you know beforehand. You could as well just do

    use strict; use warnings; my $path='/home/something/something/something'; if ( -d "$path/BUS" ) { opendir my $VEH, "$path/BUS" or die"couldnt open the directory\n"; while(readdir $VEH ) { print "$_\n"; } }
    perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'
Re: Read Directory
by Discipulus (Canon) on May 26, 2017 at 07:02 UTC

    As wise Corion you are not checking the right thing:

    you start the script in the directory /one then you open /one/two/three reading it. If you say cd four you'll go in /one/four not in /one/two/three/four

    Take a read of Cwd


    #!usr/bin/perl # ADD THESE TWO LINES! use strict; use warnings; # so you are forced to declare variables with my my $path='/home/something/something/something'; opendir(DIR,$path) or die"couldnt open the directory\n"; # parens not needed # UPDATE: assignement to $_ is needed with older perls: nowadays while +(readdir DIR) will suffice # as choroba spotted it is since 5.12 that readdir automatically feeds + $_ # doc says: As of Perl 5.12 you can use a bare readdir in a while loop +, which will set $_ on every iteration. while($_ = readdir DIR) { # this is wrong! # if(-d BUS) if ($_ eq 'BUS' and -d $path.'/'.$_) #corrected by Corion { # append BUS to the path # infact you are not changing directory my $buspath = $path.'/'.$_; opendir(VEH, $buspath) or die"couldnt open the directory [$bus +path]\n"; while($_ = readdir VEH) { print "$_\n" if -f $buspath.'/'.$_; } } }

    You can profit of Re: Win32 Recursive Directory Listing


    There are no rules, there are no thumbs..
    Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.
Re: Read Directory
by thanos1983 (Parson) on May 26, 2017 at 10:47 UTC

    Hello Nansh,

    As all the monks have already advised you, you need to use the $path when you are moving around. Alternatively you can use the chdir e.g. chdir('path/to/dir') or die "$!"; to switch to the directory remember to use it every time you move around.

    Hope this helps.

    Seeking for Perl wisdom...on the process of learning...not there...yet!
Re: Read Directory
by Corion (Patriarch) on May 26, 2017 at 06:58 UTC

    -d BUS will not do what you think it does. It checks (in an arcane way) for a directory named "BUS", but in the current directory, not in the directory denoted by $path.

    Maybe you simply want to use the full path directly?

    if( -d "$path/BUS" ) { ... }
      It checks (in an arcane way) for a directory named "BUS", but in the current directory

      Sorry, no. BUS is just a bareword here with no meaning whatsoever for -d.

      perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'

        Had I tested my assumption, I would have come to that same conclusion:

        perl -we "print -d SCRIPTS" Name "main::SCRIPTS" used only once: possible typo at -e line 1. -d on unopened filehandle SCRIPTS at -e line 1. Use of uninitialized value in print at -e line 1.

        I thought the bareword would be treated as a string, but it gets treated as a filehandle.

        That's what I get for not using the old ways but lexical filehandles wherever I can :).

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1191269]
Approved by Corion
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others taking refuge in the Monastery: (3)
As of 2024-05-27 22:47 GMT
Find Nodes?
    Voting Booth?

    No recent polls found