CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
INDEX
Search Posts SEARCH
POSTS
Who's Online WHO'S
ONLINE
Log in LOG
IN

Home: Perl Programming Help: Beginner:
Reading all the files from a directory

 



ravi.joshi53
New User

Sep 11, 2012, 11:28 AM

Post #1 of 8 (1450 views)
Reading all the files from a directory Can't Post

Hi, I am newbie in PERL. I am trying to read all the files from a directory. Somehow i managed my script to read single file. Below is the script, which i am using to read single file-


Code
#!/usr/bin/perl 
$MY_FILE = "me.txt";
open(MY_FILE) or die("Could not open file ".$MY_FILE);
foreach $line (<MY_FILE>) {
my @values = split ' ', $line;
foreach my $val (@values) {
print "$val\n";
}
}
close(MY_FILE);


I tried to modified the above script to read all the files from a directory in following manner but didn't succeed.


Code
$d = $ARGV[0]; 
opendir my $dir, $d or die "Can not open directory ".$d;
foreach my $MY_FILE (readdir $dir){
open($d/MY_FILE) or die("Can not open file ".$d.$MY_FILE);
foreach $line (<MY_FILE>) {
my @values = split ' ', $line;
foreach my $val (@values) {
print "$val\n";
}
}
close(MY_FILE);
}
closedir $dir;


Somebody tell me about the mistake and modifications too. Thank you in advance... :)


Laurent_R
Veteran / Moderator

Sep 11, 2012, 11:42 AM

Post #2 of 8 (1442 views)
Re: [ravi.joshi53] Reading all the files from a directory [In reply to] Can't Post

Do you get an error message? Does it stop nowhere? Does it not compile? Please state the problem you encounter.

Take a look at the glob function which is usually easier to use than opendir. It returns a list a files with their relative path.


ravi.joshi53
New User

Sep 11, 2012, 12:00 PM

Post #3 of 8 (1439 views)
Re: [Laurent_R] Reading all the files from a directory [In reply to] Can't Post

I just modified open file to this way.

Code
open(MY_FILE) or die("Can not open file ".$MY_FILE);

I am getting below message while trying to run it.
Use of uninitialized value $MY_FILE in open at test.pl line 6. To be more precise, Line 6 contain open function.


Zhris
Enthusiast

Sep 11, 2012, 12:35 PM

Post #4 of 8 (1426 views)
Re: [ravi.joshi53] Reading all the files from a directory [In reply to] Can't Post

Hi,

As suggested by Laurent_R, glob can be used to neatly read the contents of a directory:


Code
my $dir_path = $ARGV[0]; 

while (<"$dir_path/*">) { print "$_\n"; }


Rather than telling you everything thats wrong with your code, here is an example that prints the first line of every file in the directory supplied. Possibly compare it against your own code to see where you have gone wrong:


Code
#!/usr/bin/perl 
use strict;
use warnings;

my $dir_path = $ARGV[0];

opendir my $dh, $dir_path or die "cannot open dir $dir_path: $!";

foreach my $file_path ( map { "$dir_path/$_" } grep { -f "$dir_path/$_" } readdir $dh )
{
open my $fh, '<', $file_path or die "cannot open file $file_path: $!";

while (my $line = <$fh>)
{
chomp $line;
print "$line\n";
last;
}

close $fh;
}

closedir $dh;


Chris


(This post was edited by Zhris on Sep 11, 2012, 12:50 PM)


ravi.joshi53
New User

Sep 11, 2012, 1:21 PM

Post #5 of 8 (1412 views)
Re: [Zhris] Reading all the files from a directory [In reply to] Can't Post

Cheers Zhris, Thank you for the answer. The problem was because of wrong Open Function in my code. However i just have two doubts in your code.
(1) What is the use of grep { -f "$dir_path/$_" }? The script is working fine after removing it also.

(2) While creating file path, you are using my $file_path = $dir_path . '/' . $file_name; . Currently i am on Ubuntu, so file separator ='/' is working fine, what about Windows? Will the same file separator work there? If not, then suggest some alternate to get file separator dynamically based on the OS.


Once again, you make me happy. Cheers!!!


Zhris
Enthusiast

Sep 11, 2012, 1:49 PM

Post #6 of 8 (1405 views)
Re: [ravi.joshi53] Reading all the files from a directory [In reply to] Can't Post

Hi ravi,

I had updated my code since you read, which I guess makes things more complicated with use of map too.

I am using grep to ensure elements readdir returns that are not files (namely directories) are removed. Grep is fundamentally a list filter operation. If you are concerned, the map is used to translate the file_name into a full file_path rather than doing it inside the loop.

I tested the code on Windows and the / file separator works fine (see the actual $dir_path I tested with below). I've actually never considered this issue before now (i'll look into it!).


Code
my $dir_path = 'C:/Users/Chris/Desktop/Perl bits bobs';


Thanks,

Chris


(This post was edited by Zhris on Sep 11, 2012, 1:52 PM)


ravi.joshi53
New User

Sep 11, 2012, 2:10 PM

Post #7 of 8 (1395 views)
Re: [Zhris] Reading all the files from a directory [In reply to] Can't Post

Hi Zhris,
Yeah... Absolutely right. The reason why grep { -f "$dir_path/$_" } is working fine for me is that there is no subdirectories inside the input directories. You cleverly handled it. Regarding use of map function here will reflect to increase in performance. Brilliant you.

Thank you ....


Zhris
Enthusiast

Sep 11, 2012, 2:39 PM

Post #8 of 8 (1390 views)
Re: [ravi.joshi53] Reading all the files from a directory [In reply to] Can't Post

Hi ravi,

No problem. It was best to post a fresh example rather than explain the different issues / potential improvements with your original script on a line by line basis.

For your information, I found this post useful regarding path separators across systems (http://www.perlmonks.org/?node_id=110030).

Chris


(This post was edited by Zhris on Sep 11, 2012, 2:41 PM)

 
 


Search for (options) Powered by Gossamer Forum v.1.2.0

Web Applications & Managed Hosting Powered by Gossamer Threads
Visit our Mailing List Archives