views:

184

answers:

5

For example:

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

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

+1  A: 
open (PS,"tail -n 1 $file|");
if($l=<PS>)
  {print"$l"}
else
  {print"$file is empty\n"}
oraz
+5  A: 

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>;
}
FM
A: 

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;
derby
A: 

You are using the open command incorrectly.

You probably wanted to say

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

(note that trailing |) which will make the output of those commands accessible through filehandle PS. But what you really probably want is one of:

$output = `tail -n 1 $file | grep win`;
$output = qx(tail -n 1 $file | grep win);
$output = readpipe("tail -n 1 $file | grep win");

Then you can test whether $output is empty, or do something with the contents of $output.

Your initial open statement

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

will look for a file for called ./"tail -n 1 $file | grep win" and try to open it for reading.

mobrule
+3  A: 

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 []
Greg Bacon