Question

For example:

open (PS , " tail -n 1 $file | grep win " );

I want to find whether the file handle is empty or not.

Was it helpful?

Solution

You can also use eof to check whether a file handle is exhausted. Here is an illustration based loosely on your code. Also note the use of a lexical file handle with the 3-arg form of open.

use strict;
use warnings;

my ($file_name, $find, $n) = @ARGV;

open my $fh, '-|', "tail -n $n $file_name | grep $find" or die $!;

if (eof $fh){
    print "No lines\n";
}
else {
    print <$fh>;
}

OTHER TIPS

Although calling eof before you attempt to read from it produces the result you expect in this particular case, give heed to the advice at the end of the perlfunc documentation on eof:

Practical hint: you almost never need to use eof in Perl, because the input operators typically return undef when they run out of data, or if there was an error.

Your command will produce at most one line, so stick it in a scalar, e.g.,

chomp(my $gotwin = `tail -n 1 $file | grep win`);

Note that the exit status of grep tells you whether your pattern matched:

2.3 Exit Status

Normally, the exit status is 0 if selected lines are found and 1 otherwise …

Also, tail exits 0 on success or non-zero on failure. Use that information to your advantage:

#! /usr/bin/perl

use strict;
use warnings;

my $file = "input.dat";
chomp(my $gotwin = `tail -n 1 $file | grep win`);

my $status = $? >> 8;
if ($status == 1) {
  print "$0: no match [$gotwin]\n";
}
elsif ($status == 0) {
  print "$0: hit! [$gotwin]\n";
}
else {
  die "$0: command pipeline exited $status";
}

For example:

$ > input.dat 
$ ./prog.pl 
./prog.pl: no match []
$ echo win >input.dat
$ ./prog.pl 
./prog.pl: hit! [win]
$ rm input.dat 
$ ./prog.pl 
tail: cannot open `input.dat' for reading: No such file or directory
./prog.pl: no match []
open (PS,"tail -n 1 $file|");
if($l=<PS>)
  {print"$l"}
else
  {print"$file is empty\n"}

well ... scratch this ... I didn't make the connection about the filehandle actually being the output of a pipe.

You should use stat to determine the size of a file but you're going to need to ensure the file is flushed first:

#!/usr/bin/perl

my $fh;
open $fh, ">", "foo.txt" or die "cannot open foo.txt - $!\n";

my $size = (stat $fh)[7];
print "size of file is $size\n";

print $fh "Foo";

$size = (stat $fh)[7];
print "size of file is $size\n";

$fh->flush;

$size = (stat $fh)[7];
print "size of file is $size\n";

close $fh;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top