首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何解析下一行包含相关数据的数组

如何解析下一行包含相关数据的数组
EN

Stack Overflow用户
提问于 2012-02-10 00:57:50
回答 2查看 154关注 0票数 0

打开我的日志,'>',$outpath或$logger->logdie(“错误:无法打开$outpath。它可能是打开的。:$!”);我有一个命令,它的输出被读取到一个数组中(用换行符拆分),然后进行解析。当我使用本地$/ = "";从文件中窃取它时,它工作得很好。但是我读到有一个中间文件是浪费的,并改变了它。现在我根本看不懂下一行了!以下是需要解析的不同类型的数据输出:

代码语言:javascript
复制
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。

这是我的代码,

代码语言:javascript
复制
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";
}

当然,正如你可能已经注意到的,其他的根本不起作用,我得到的是fcalias替身。但是无论我怎么尝试,我都不能添加获取我需要的输出。这个子例程是一个更大的脚本的一部分,这个脚本已经过优化,只是缺少这个part.....Help!

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

代码语言:javascript
复制
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");
       }
}
EN

回答 2

Stack Overflow用户

发布于 2012-02-10 01:17:28

要回答标题中的问题,您可以

  1. 向前看下一行,或
  2. 在阅读下一行时修补前一行的结果。

else根本不能工作,你意识到你已经注释掉了一半吗?它不会写入OUTFILE?你提供的输入都不能到达它吗?您跳过了空行,并且每隔一行匹配一次。当您匹配^fcalias (或耗尽数据)并发现它设置的变量尚未重置时,执行else的正文;同时,在pwwn|interface用例中重置这些变量。

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

代码语言:javascript
复制
open DATA, "fcalias-stuff |" or die $!;
票数 2
EN

Stack Overflow用户

发布于 2012-02-10 02:49:13

如果逐行阅读数据会使您的工作更加困难,那么您为什么要这样做呢?发出声音的问题是,所有的东西都会一次进入内存。如果你的文件足够小,这应该不是问题。

关于你的风格的额外评论。不应使用全局文件句柄(OUTFILE)。这些都是全局变量,所有问题都随之而来。如果你在一个递归函数中有一个带有全局文件句柄的open,那么你将总是关闭并重新打开这个文件句柄。

最好像在open my $outfile, '>', $outpath or die中一样使用本地文件句柄。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9215217

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档