Alyssa Low
Alyssa Low

Reputation: 103

Reading a line from a file using perl

First off, I have to find the existence of the pass and fail files in the subdirectories. Then, I need to read the first line of the pass/fail file. I thought of separating the $file1 and $file to differentiate it. I'm very new to perl so I know my approach is very bad.

I trying to figure out how to combine my current code to read the files I checked exists.

use strict;
use File::Find 'find';

my $file = 'pass.txt';
my $file1 = 'fail.txt';
my @directory = ('ram1','ram2');

sub check 
{
    if ( -e $_ && $_ eq $file ) 
        {                                                                      
            print "Found file '$_' in directory '$File::Find::dir'\n";                                     
        }  
    elsif ( -e $_ && $_ eq $file1 ) 
        {                                                                      
            print "Found file '$_' in directory '$File::Find::dir'\n";                                     
        }  
}
find (\&check,@directory);

Is it possible I use the code below for the first if condition? I know it doesn't work but I'm not sure what to do next as the fail and pass text are inside the directories.

if (open my $File::Find::dir, '<', $file){ 
my $firstLine = <$File::Find::dir>; 
close $firstLine;

Any suggestions would be helpful!

Upvotes: 1

Views: 99

Answers (3)

ikegami
ikegami

Reputation: 385789

If you just want to look just in ram1 and ram2, there's no point in using File::Find. That is used for recursive searches, meaning if you want to search all the subdirectories of ram1 and ram2. (And for that, I'd use File::Find::Rule over File::Find; it's much cleaner.)

my @dir_qfns = ( 'ram1', 'ram2' );

for my $dir_qfn (@dir_qfns) {
   for my $fn ('pass.txt', 'fail.txt') {
      my $file_qfn = "$dir_qfn/$fn";
      open(my $fh, '<', $file_qfn)
         or warn("Can't open \"$file_qfn\": $!\n"), next;

      defined( my $first_line = <$fh> )
         or warn("\"$file_qfn\" is empty\n"), next;

      print("$file_qfn: $first_line");
   }
}

If it's ok for a file to be missing, then you can ignore that error (ENOENT).

Similarly, you don't need to output an error message if the file is empty.

my @dir_qfns = ( 'ram1', 'ram2' );

for my $dir_qfn (@dir_qfns) {
   for my $fn ('pass.txt', 'fail.txt') {
      my $file_qfn = "$dir_qfn/$fn";

      my $fh;
      if (!open($fh, '<', $file_qfn)) {
         warn("Can't open \"$file_qfn\": $!\n") if $!{ENOENT};
         next;
      }

      defined( my $first_line = <$fh> )
         or next;

      print("$file_qfn: $first_line");
   }
}

Upvotes: 2

Polar Bear
Polar Bear

Reputation: 6798

OP's code does not make much sense. Perhaps OP is looking for something of next kind

use strict;
use warnings;
use feature 'say';

my $dir   = shift || 'some_dir_to_start_from';
my @files = qw/pass.txt fail.txt/;
my $match = join '|', @files;
my $regex = qr/\b($match)\b/;

files_lookup($dir,$regex);

exit 0;

sub files_lookup {
    my $dir = shift;
    my $re  = shift;
    
    for ( glob("$dir/*") ) {
        files_lookup($_) if -d;

        next unless /$re/;
        
        if( -f ) {
            say "File: $_";

            open my $fh, '<', $_
                or die "Couldn't open $_";
            
            my $line = <$fh>;
            say $line;
            
            close $fh;
        }       
    }

Upvotes: 0

JoelFan
JoelFan

Reputation: 38714

if (open my $f, '<', 'pass.txt') { 
  my $firstLine = <$f>; 
  close $f;
}

Upvotes: 1

Related Questions