【问题标题】:elininate some lines from data set从数据集中消除一些行
【发布时间】:2011-10-29 11:25:45
【问题描述】:

我很想从我的数据集中得到一些数据。

#!/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";
         }
      }
   }
}

这是我在运行程序时得到的——我试图从数据集中获取“无法读取 > 文件”

% ./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/islnd2/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

我尝试将它们从while循环中过滤出来,但它不起作用,并且程序中没有第52行,它只进入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;
             }
         }
      }
   }

【问题讨论】:

  • 感谢 Quintin 我很感激

标签: perl loops next


【解决方案1】:

Line 52 指的是zmore 脚本中的行,而不是您的 perl 脚本中的行。

要解决您的问题,请先测试该文件是否存在于您的 perl 脚本中,然后再将其交给其他人。

my $archive = "/data/archive/$folder_dates[$x]/$just_ecps[$j]/ghistogram.gz";
next unless (-r $archive);

-r 检查文件是否存在以及当前用户是否可以读取。所以next unless (-r $file) 将进入循环的下一次迭代,除非文件存在并且可读。

(这很有趣 - 如果在您尝试读取这些文件时某些东西正在删除(或更改其所有权),open 仍然可能失败。如果这不是安全敏感的,那么这不是太担心,但请记住这一点。)

两个提示:

  • zmore 旨在供人类使用,而不是脚本。如果输出是分页的,您的脚本一点也不关心。所以你应该使用gunzip -c $file(或者如果你没有gunzip,可能是gzip -cd,不确定那个)。
  • 始终检查open 是否成功,否则您将在某些时候尝试操作无效的文件句柄,这会导致更多错误。并且始终close 您打开的内容。

所以我会将您的脚本更改为:

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;

最后,zmore 错误消息正在打印到 STDERR。如果您只想隐藏这些消息(而不是修复它们),只需将其重定向到日志文件(或 /dev/null):

% ./read_in_ghistogram2 2> errors.log

【讨论】:

  • 我的老板让我使用 zmore,所以我非常喜欢 gunzip -c。
  • 我还没有运行代码 - 我不确定我是否理解“不!”在公开声明之前....谢谢你
  • open 如果成功则返回0,否则返回非零。 0 在布尔上下文中为假,!0 为真。所以如果open 失败,!open(...) 为真。
  • 如果你想让它更明确,请使用my $rc = open(...); if ($rc ne 0) { # open failed }。但if (!open(...)) 构造相对常见。
猜你喜欢
  • 2016-11-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-12
  • 1970-01-01
  • 2019-10-25
相关资源
最近更新 更多