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

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

I need to read all the files in a directory line by line with one file handle. But I am getting error when it reads the first file

opendir(my $dh, "/tmp/files"); my @files=readdir($dh); closedir $dh; my $index = 0; $index++ until $files[$index] eq "."; splice(@files, $index, 1); $index++ until $files[$index] eq '..'; splice(@files, $index, 1); foreach my $file ( @files ) { print "\n\nThe File is $file\n\n"; open (MYFILE, "<$file") or die $! ; while (<MYFILE>) { chomp; if ( $_ =~ m/map/i ) { print "$_ in $file\n"; } } close (MYFILE); } Error [root@r01mgt functionaltest]# perl checkfunctional.pl The File is mrbench_result No such file or directory at checkfunctional.pl line 22.

Replies are listed 'Best First'.
Re: Reading all files in a directory with one filehandle
by tinita (Parson) on Apr 03, 2013 at 09:40 UTC
    The array @files only contains the filenames without the full path. Prepend the path of the directory to the filename. And please use some more modern code for open:
    open my $fh, "<", "/tmp/files/$file" or die $!;

    The code to ignore . and .. also looks strange to me. I usually do
    my @files = grep { not m/^\.\.?$/ } readdir $dh;

      Figured out the problem. I am working on the code this is just one sample part and need modification. True we should use more modern code

        See also readdir documentation for further explanation and examples.

Re: Reading all files in a directory with one filehandle
by Loops (Curate) on Apr 03, 2013 at 09:37 UTC
    Just using glob should work, shouldn't cause an error:
    foreach my $file ( glob('/tmp/files/*') ) { print "\n\nThe File is $file\n\n"; open (MYFILE, "<$file") or die $! ; while (<MYFILE>) { chomp; if ( $_ =~ m/map/i ) { print "$_ in $file\n"; } } close (MYFILE); }
Re: Reading all files in a directory with one filehandle
by blue_cowdawg (Monsignor) on Apr 03, 2013 at 18:54 UTC

    Dirty nasty way.. but it works...

    #!/usr/bin/perl -w use strict; # # This is a rotten hack... open FH1,"cat /tmp/* |" or die "Cat died:$!"; while (my $line=<FH1>){ # etc. etc. etc. }


    Peter L. Berghold -- Unix Professional
    Peter -at- Berghold -dot- Net; AOL IM redcowdawg Yahoo IM: blue_cowdawg
Re: Reading all files in a directory with one filehandle
by hdb (Monsignor) on Apr 03, 2013 at 09:41 UTC

    You seem to try to open a file called mrbench_result that lives in /tmp/files but in the folder that the script lives (functionaltest?).

Re: Reading all files in a directory with one filehandle
by kejohm (Hermit) on Apr 03, 2013 at 22:32 UTC

    You could also use the special behaviour of the null filehandle <>. It reads file names from the @ARGV variable, which you can populate via the command line or manually. It opens each file specified and reads one line at a time. Here is a sample:

    #!perl use 5.012; # Populate @ARGV unless files are specified on the command line @ARGV = grep { -f } glob('/tmp/files/*') unless @ARGV; while (<>) { chomp; if ( m/map/i ) { # The name of the current file is in the special variable $ARG +V say "$_ in $ARGV"; } }

    See I/O Operators in perlop for more info.