I am rying to get some line out of my data set.
#!/usr/local/bin/perl
use Date::Calc qw(Add_Delta_Days);
my @just_ecps;
my @folder_dates;
my @ecp_dot_tee_array = `grep ISLAND ~/data/files/grit.t`;
foreach (@ecp_dot_tee_array){
($ecp, undef, undef, undef, undef, undef) = split (/\s+/, $_);
push (@just_ecps, $ecp);
}
for ($h = 1; $h <= 5; $h++){
my (undef, undef, undef, $day, $month, $year) = localtime();
$year+=1900;
$month+=1;
($year, $month, $day) = Add_Delta_Days($year, $month, $day, -$h );
if ($month < 10 ){
$month = "0$month";
}
if ($day < 10 ){
$day = "0$day";
}
push (@folder_dates, "$year$month$day");
}
for ( $j=0; $j <=$#just_ecps ; $j++){
for ($x=0; $x<=$#folder_dates ; $x++){
open FILEHANDLE , "zmore /data/ibprod/archive/$folder_dates[$x]/$just_ecps[$j] /ghistogram.gz | ";
@archive_average = (<FILEHANDLE>);
foreach $line(@archive_average){
if ($line =~ /ave:\s+(\d+\.\d+)\s/){
print $1;
sleep 1;
print "\n";
}
}
}
}
This is what i get when i run the program - i am trying to get the 'cannot read the > files out of the data set
% ./read_in_ghistogram2
0.00414601
0.0044511
0.00387373
/usr/bin/zmore: line 52: /home/data/archive/20110814/islnd1/ghistogram.gz: No such file or directory
/usr/bin/zmore: line 52: /home/data/archive/20110813/islnd1/ghistogram.gz: No such file or directory
0.00309721
0.00302753
0.00307702
/usr/bin/zmore: line 52: /home/data/archive/20110814/isln开发者_如何学God2/ghistogram.gz: No such file or directory
/usr/bin/zmore: line 52: /home/data/archive/20110813/islnd2/ghistogram.gz: No such file or directory
0.00324729
0.00295381
0.00301736
/usr/bin/zmore: line 52: /home/data/archive/20110814/islnd3/ghistogram.gz: No such file or directory
/usr/bin/zmore: line 52: /home/data/archive/20110813/islnd3/ghistogram.gz: No such file or directory
I tried filtering them out of the while loop, but it does not work, and ther is not line 52 in the program, it only goes to 42
for ( $j=0; $j <=$#just_ecps ; $j++){
for ($x=0; $x<=$#folder_dates ; $x++){
#print "/home/ibprod_archive/$folder_dates[$x]/$just_ecps[$j]/ghistogram.gz";
open FILEHANDLE , "zmore /data/archive/$folder_dates[$x]/$just_ecps[$j]/ghistogram.gz | ";
while (<FILEHANDLE>) {
next if ($_ =~ '/No such file or directory/');
push (@archive_average,$_);
foreach $line(@archive_average){
if ($line =~ /\save:\s+(\d+\.\d+)\s/){
print $line;
sleep 1;
}
}
}
}
Line 52
refers to the line in the zmore
script, not in your perl script.
To fix your issue, test if the file exists in your perl script before handing it over to something else.
my $archive = "/data/archive/$folder_dates[$x]/$just_ecps[$j]/ghistogram.gz";
next unless (-r $archive);
-r
checks both that the file exists and is readable by the current user. So next unless (-r $file)
will go to the next iteration of the loop unless the file exists and is readable.
(This is racy - if something is removing (or changing ownership of) those files while you are trying to read them, open
can still fail. If this is not security sensitive, then that's not too much of a worry, but keep that in mind.)
Two tips:
zmore
is meant to be used by humans, not scripts. You script does not care one bit if the output is paginated. So you should be usinggunzip -c $file
(or maybegzip -cd
if you don't havegunzip
, not sure about that one).- Always check that
open
succeeded, otherwise you'll be trying to manipulate invalid filehandles at some point, which will get you more errors. And alwaysclose
what you opened.
So I'd change your script to:
my $archive = "/data/archive/$folder_dates[$x]/$just_ecps[$j]/ghistogram.gz";
next unless (-r $archive);
if (!open(FILEHANDLE, "<", "gunzip -c $archive|")) {
print STDERR "Error processing $archive: $!\n"; # optional
next;
}
while (<FILEHANDLE>) {
...
}
close FILEHANDLE;
Lastly, the zmore
error message is being printed to STDERR. If all you want to do is hide those messages (rather than fixing them), simply redirect that to a log file (or /dev/null
):
% ./read_in_ghistogram2 2> errors.log
精彩评论