0

open my $outfile, '>', $outpath or $logger->logdie("Error: Can't open $outpath. It may be open.:$!");我有一个命令,其输出被读入数组(由换行符分割)然后解析。当我过去常常从文件中啜饮它并只使用本地 $/ = ""; 时,它工作得很好。但我读到有一个中间文件是浪费的,并改变了它。现在我根本看不懂下一行!!!以下是需要解析的不同类型的数据输出:

fcalias name DA540_MAE_I0032 vsan 24
pwwn X0:00:00:63:ab:03:86:e1

fcalias name NAEMS02_DH6_AUX0 vsan 53

fcalias name NRTMF02_DM3_BE0 vsan 53

fcalias name DMSRT56-777_09C0 vsan 53
interface fc2/33 swwn 20:13:ev:0d:ed:3e:da:00

当 pwwn 出现时,我希望它添加到 fcalias,变量“type”= pwwn/swwn/none 取决于数据。

这是我的代码,

sub fcalias 
   { my ($path, $commandfile, $switch_ip, @data) = @_;
     my $outpath = "$path${switch_ip}_${commandfile}.csv";  
     open my $outfile, '>', $outpath or $logger->logdie("Error: Can't open $outpath. It   may be open.:$!");    
     my ($type, $fcalias, $vsan);

     while  (@data) 
    { $_ = shift(@data); 
      s/^\s+//;       # Delete leading whitespaces
      next if (/^$/); # Skip empty lines

      if  (/^fcalias name (\S+) vsan (\S+)/) 
         {($fcalias, $vsan) = ($1, $2);next;} 

      elsif (/^pwwn (\S+)/) 
           {$type = "pwwn"; my $pwwn = $1; 
            print ($outfile, "$fcalias;$vsan;$type;$pwwn;;;$switch_ip\n");
           } 

      elsif  (/interface (\S+) swwn (\S+)/) 
            {$type = "interface"; 
            my ($interface,$swwn) = ($1,$2); 
            print ($outfile, "$fcalias;$vsan;$type;;$swwn;$interface;$switch_ip\n");
            } 

      else  {$type = "none";
            print ($outfile, "$fcalias;$vsan;$type;;;;$switch_ip\n");
           # print "$_ \n";
            }
    }
    print "..................DONE\n";
}

当然,您可能已经注意到,else 根本不起作用,我得到 fcalias 双打。但无论我尝试什么,我都无法添加我需要的输出。这个子程序是一个更大的脚本的一部分,该脚本已经过优化,只是缺少这部分.....帮助!

作为参考,这是旧的代码循环。请原谅长帖子和代码格式。我试过了。谢谢!

local $/ = "";
while (<DATA>) 
{ if  ($_ =~ m/^fcalias name (\S+) vsan (\S+)\s+pwwn (\S+)/) 
     { my ($fcalias, $vsan, $pwwn) = ($1, $2, $3);
       my $type = "pwwn";
       print (OUTFILE "$fcalias;$vsan;$type;$pwwn;;;$switch_ip\n");  
      } 

  elsif  ($_ =~ m/^fcalias name (\S+) vsan (\S+)\s+interface (\S+) swwn (\S+)/) 
      { my ($fcalias, $vsan, $interface, $swwn) = ($1, $2, $3 ,$4);
        my $type = "interface"; 
        print (OUTFILE "$fcalias;$vsan;$type;;$interface;$swwn;$switch_ip\n");
       } 

  else  ($_ =~ m/^fcalias name (\S+) vsan (\S+)/) 
       { my ($fcalias, $vsan) = ($1, $2);
         my $type = "none";
         print (OUTFILE "$fcalias;$vsan;$type;;;;$switch_ip\n");
       }
}
4

2 回答 2

2

要回答标题中的问题,您要么

  1. 向前看下一行,或

  2. 当您阅读下一行时,修补读取上一行的结果。

根本不工作,else你知道你已经评论了一半吗?并且它不写入 OUTFILE ? 而且您提供的任何输入都不会到达它? 您正在跳过空行并匹配所有其他行。匹配^fcalias(或用完数据)时执行else的body,发现它设置的变量没有被重置;此外,在 pwwn|interface 案例中重置这些变量。

要避免中间文件但仍使用旧代码,请使用带有管道的 open 。例如,

open DATA, "fcalias-stuff |" or die $!;
于 2012-02-09T17:17:27.983 回答
1

如果逐行读取数据使您的工作更加困难,您为什么要这样做?啜饮的问题在于,一切都会立即进入记忆。如果您的文件足够小,这应该不是问题。

对您的风格的附加评论。您不应使用全局文件句柄 ( OUTFILE)。这些是带有所有问题的全局变量。如果您在递归函数中使用全局文件句柄打开,例如,您将始终关闭并重新打开文件句柄。

更好地使用本地文件句柄,如open my $outfile, '>', $outpath or die.

于 2012-02-09T18:49:13.463 回答