Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typo3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl 逐块读取文件_Perl_Nagios - Fatal编程技术网

Perl 逐块读取文件

Perl 逐块读取文件,perl,nagios,Perl,Nagios,我正在使用perl,希望读取具有以下结构的外部文件(本文末尾的完整代码): 这些块位于文件的不同部分,状态块位于上部,注释块位于下部。(每个commentblock与特定的statusblock相关) 现在我正试图逐行扫描文件,因此我首先遇到一个statusblock,读取某个参数(即parameter2),最后在文件的其余部分搜索具有相同参数的commentblock 我为解决这个问题而编写的脚本是非常嵌套的,除了它只找到第一个statusblock、它对应的commentblock,然后离开

我正在使用perl,希望读取具有以下结构的外部文件(本文末尾的完整代码):

这些块位于文件的不同部分,状态块位于上部,注释块位于下部。(每个commentblock与特定的statusblock相关)

现在我正试图逐行扫描文件,因此我首先遇到一个statusblock,读取某个参数(即parameter2),最后在文件的其余部分搜索具有相同参数的commentblock

我为解决这个问题而编写的脚本是非常嵌套的,除了它只找到第一个statusblock、它对应的commentblock,然后离开循环之外,还有很多东西要找到。欢迎考虑此问题的任何帮助

这是完整的代码

while ($line = <SF>) {
  if ($line =~ /servicestatus/) {
    while ($line = <SF>) {
      if ($line =~ /service_description/) {
        $service_desc = $line;
        while ($line = <SF>) {
          if ($line =~ /servicecomment/) {
            while ($line = <SF>) {
              if ($line =~ /service_description/) {
                $service_desc2 = $line;
                if ($service_desc eq $service_desc2) {
                  while ($line = <SF>) {
                    if ($line =~ /comment_id/) {
                      if ($line =~ m/(\d+)/) {
                        $comment_id = $1;
                        while ($line = <SF>) {
                          if ($line =~ /entry_time/) {
                            if ($line =~ m/(\d+)/) {
                              $entry_time = $1;
                              if ($entry_time < $time_oldest) {

                                # Kommando wird in die Commandpipe geladen
                                open(CP, ">>$o_commandpipe") or die("nagios.cmd not found");

                                # Befehl wird ausgegeben, External Command DEL_SVC_COMMENT wird ausgeführt
                                print {CP} "[$time_now] DEL_SVC_COMMENT;$comment_id;$time_now\n";
                                close(CP);
                                print("Comment $comment_id deleted.\n");
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

close SF;
while($line=){
如果($line=~/servicestatus/){
而($line=){
如果($line=~/service\u description/){
$service_desc=$line;
而($line=){
如果($line=~/servicecomment/){
而($line=){
如果($line=~/service\u description/){
$service_desc2=$line;
if($service_desc eq$service_desc2){
而($line=){
如果($line=~/comment\u id/){
如果($line=~m/(\d+/){
$comment_id=$1;
而($line=){
如果($line=~/entry\u time/){
如果($line=~m/(\d+/){
$entry_time=$1;
如果($entry_time<$time_最早){
#科曼多·沃德在格拉登指挥管
打开(CP,“>>$o_commandpipe”)或死亡(“未找到nagios.cmd”);
#在使用Ausgeben之前,外部命令DEL_SVC_注释使用ausgeführt
打印{CP}“[$time\u now]DEL\u SVC\u COMMENT;$COMMENT\u id;$time\u now\n”;
关闭(CP);
打印(“注释$Comment\u id已删除。\n”);
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
关闭SF;
为了更好地理解:此脚本适用于nagios(服务器监视工具),应该在特定时间后删除特定服务的用户定义注释

提前谢谢

怎么样

my $file; { local $/; $file = <$fh>; }
while ($file =~ /^\s*(\S+)\s*\{([^}]*)\}/mg) {
   my $name  = $1;
   my $block = $2;
   ...
}
my$文件;{local$/;$file=;}
而($file=~/^\s*(\s+)\s*\{([^}]*)\}/mg){
我的$name=$1;
my$block=$2;
...
}
怎么样

my $file; { local $/; $file = <$fh>; }
while ($file =~ /^\s*(\S+)\s*\{([^}]*)\}/mg) {
   my $name  = $1;
   my $block = $2;
   ...
}
my$文件;{local$/;$file=;}
而($file=~/^\s*(\s+)\s*\{([^}]*)\}/mg){
我的$name=$1;
my$block=$2;
...
}

有几点建议:

  • 嵌套循环不是解决问题的合适设计。您需要的是一个遍历文件的循环,其中包含逻辑
  • 具有相等参数的注释块是否始终位于其相应的服务状态块之后?如果没有,您还需要重新考虑逐行遍历文件的设计
  • 块是否总是用空行分隔,如示例中所示?如果是这样,您可以设置
    $/=“\n\n”。然后可以逐块而不是逐行读取文件
下面是一个如何做到这一点的示例,使用散列来跟踪要删除的内容。我假设所有的块都是用空行分隔的,但如果不是这样,您可以很容易地将其应用于ikegami遍历文件的方法

use warnings;
use strict;

{
    my %delete_params;
    local $/ = "\n\n";
    while (<DATA>)
    {
        if (/^servicestatus/ and /parameter2 = (.*)/)
        {
            $delete_params{$1}++; #Delete comments with this parameter.
        }
        elsif (/^servicecomment/ and /parameter2 = (.*)/ and 
               exists $delete_params{$1})
        {
            next;   #Comment matched; do not print.
        }

        print $_;
    }   
}

__DATA__
servicestatus {
  parameter1 = abc
  parameter2 = abc
  parameter3 = abc
  }

servicestatus {
  parameter1 = abc
  parameter2 = xyz
  parameter3 = abc
  }

servicecomment {
  parameter1 = def
  parameter2 = abc
  parameter3 = ghi
  }

servicecomment {
  parameter1 = def
  parameter2 = xyz
  parameter3 = ghi
  }

servicecomment {
  parameter1 = def
  parameter2 = rrr
  parameter3 = ghi
  }
使用警告;
严格使用;
{
我的%delete_参数;
本地$/=“\n\n”;
而()
{
如果(/^servicestatus/和/参数2=(.*)/)
{
$delete_params{$1}++;#使用此参数删除注释。
}
elsif(/^servicecomment/和/参数2=(.*))/和
存在$delete_参数{$1})
{
下一步;#注释匹配;不打印。
}
打印美元;
}   
}
__资料__
服务状态{
参数1=abc
参数2=abc
参数3=abc
}
服务状态{
参数1=abc
参数2=xyz
参数3=abc
}
服务评论{
参数1=def
参数2=abc
参数3=ghi
}
服务评论{
参数1=def
参数2=xyz
参数3=ghi
}
服务评论{
参数1=def
参数2=rrr
参数3=ghi
}

有几点建议:

  • 嵌套循环不是解决问题的合适设计。您需要的是一个遍历文件的循环,其中包含逻辑
  • 具有相等参数的注释块是否始终位于其相应的服务状态块之后?如果没有,您还需要重新考虑逐行遍历文件的设计
  • 块是否总是用空行分隔,如示例中所示?如果是这样,您可以设置
    $/=“\n\n”。然后可以逐块而不是逐行读取文件
下面是一个如何做到这一点的示例,使用散列来跟踪要删除的内容。我假设所有的块都是用空行分隔的,但如果不是这样,您可以很容易地将其应用于ikegami遍历文件的方法

use warnings;
use strict;

{
    my %delete_params;
    local $/ = "\n\n";
    while (<DATA>)
    {
        if (/^servicestatus/ and /parameter2 = (.*)/)
        {
            $delete_params{$1}++; #Delete comments with this parameter.
        }
        elsif (/^servicecomment/ and /parameter2 = (.*)/ and 
               exists $delete_params{$1})
        {
            next;   #Comment matched; do not print.
        }

        print $_;
    }   
}

__DATA__
servicestatus {
  parameter1 = abc
  parameter2 = abc
  parameter3 = abc
  }

servicestatus {
  parameter1 = abc
  parameter2 = xyz
  parameter3 = abc
  }

servicecomment {
  parameter1 = def
  parameter2 = abc
  parameter3 = ghi
  }

servicecomment {
  parameter1 = def
  parameter2 = xyz
  parameter3 = ghi
  }

servicecomment {
  parameter1 = def
  parameter2 = rrr
  parameter3 = ghi
  }
使用警告;
严格使用;
{
我的%delete_参数;
本地$/=“\n\n”;
而()
{
如果(/^servicestatus/和/参数2=(.*)/)
{
$delete_params{$1}++;#使用此参数删除注释。
}
elsif(/^servicecomment/和/参数2=(.*))/和
存在$delete_参数{$1})
{
下一步;#注释匹配;不优先