【问题标题】:Using grep in if statements in perl在 perl 的 if 语句中使用 grep
【发布时间】:2014-05-12 22:19:34
【问题描述】:

我有多个看起来像 dmesg 输出的日志文件。我需要将所有这些文件的某些结果解析并存储到一个输出文件中。 前输入文件1:

 .....
 Started 1399343129
 KbPerSec  1222
 KiloBytes 9302938
 Status 83
 StorageUNit unitname
 Ended 1399473434
 .......

输出文件:

  1399343129  1222  9302938 83 unitname 1399473434
  <input file2 numbers>
  <input file3 numbers>
  .....

所以,我使用 grep,并拆分 grep 结果以获得我想要的数字。这是我的代码的样子。 &lt;TRY&gt; 是我的文件句柄。

my (@grepres, @splitres);
my ($size, $start, $bw);

if(@grepres=grep{/KbPerSec/} <TRY>){
  @splitres=split(' ',$grepres[0]);
  $bw=$splitres[1];
  print "1. $bw\n";
}

if(@grepres=grep{/Started/} <TRY>){
  @splitres=split(' ',$grepres[0]);
  $start=$splitres[1];
  print "$start\n";
}

...
  1. 但我的代码只执行第一个 if,然后停止。为什么它不执行其他 if 语句?
  2. 这似乎不是一种有效的方法。我怎样才能做得更好?

【问题讨论】:

    标签: perl


    【解决方案1】:
    1. 由于列表上下文中的&lt;TRY&gt; 消耗了TRY 文件句柄中的所有数据,因此对&lt;TRY&gt; 的后续调用返回空。如果你想重用文件流中的数据,要么

    一个。将流保存到变量中

     my @try = <TRY>;
     if ( grep ..., @try ) {
        ...
     }
     if ( grep ..., @try ) { 
        ...
     }
    

    b.重新打开文件或seek回到开头

     open TRY, '<', $try_file
     ...
     if (grep ..., <TRY>) {
        ...
     }
     close TRY;
     open TRY, '<', $try_file
     if (grep ..., <TRY>) {
        ...
     }
    
     open TRY, '<', $try_file
     ...
     if (grep ..., <TRY>) {
        ...
     }
    
     seek TRY, 0, 0;  # reset cursor position to start of file
    
     if (grep ..., <TRY>) {
        ...
     }
    

    【讨论】:

      【解决方案2】:

      这是一种可能的方法,它取决于从记录到记录的字段顺序相同。

      更新:更改了结束条件匹配。

      #!/usr/bin/perl
      use strict;
      use warnings;
      
      my @data;
      while (<DATA>) {
          if (/^Started/ .. /^Ended/) {
              push @data, /^\S+ (.+)$/;
              print join(" ", splice @data), "\n" if /^Ended/;    
          }
      }
      
      __DATA__
      .....
      Started 1399343129
      KbPerSec  1222
      KiloBytes 9302938
      Status 83
      StorageUNit unitname
      Ended 1399473434
      .......
      

      打印

      1399343129  1222 9302938 83 unitname 1399473434
      

      【讨论】:

      • 如果这样做,请在 while 循环之前声明 $end,而不是在赋值中。否则你会受到perldoc.perl.org/perlsyn.html 中提到的未定义行为的影响,它说“这里是龙。”
      • @ysth 感谢您的关注 - 我做了您建议的更改。
      猜你喜欢
      • 2015-09-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-07
      • 2021-06-21
      • 1970-01-01
      相关资源
      最近更新 更多