繁体   English   中英

Perl正则表达式可捕获部分命令输出

[英]Perl regular expressions to capture parts of command output

编辑了问题:我添加了第三个功能。 我想出了一个正则表达式,它似乎是正确的。 (第一和第二功能按预期工作。)

我已经在库中编写了几个函数,并且从测试脚本中调用了这些函数。 我的正则表达式有一些问题。 有人可以帮我解决正则表达式吗?

功能一:

sub ipsec_version {
    my ($self)  = @_;
    my $cmd     = 'sudo -s ipsec version ';
    my $version = 0;

   #execute the command
   $self->execute($cmd);

   foreach my $line ( @{ $self->get_stdout() } ) {
        if ( $line =~ m/strongSwan/msx ) {
            $version = $1;
        }
    }
   return $version;

}

函数调用:

$self->{'ipsec_version'} = $self->{'ipsec_obj'}->ipsec_version();
INFO('[Startup] ipsec version is  : ' .  $self->{'ipsec_version'} );

实际输出:

Use of uninitialized value in concatenation (.) or string at ... line 37.
     ipsec version is  : 

预期产量:

strongSwan U5.1.2/K3.16.0-30-generic

命令输出:

我需要脚本来捕获预期的输出字符串

Linux strongSwan U5.1.2/K3.16.0-30-generic
Institute for Internet Technologies and Applications
University of Applied Sciences Rapperswil, Switzerland
See 'ipsec --copyright' for copyright information.

功能2:

sub ipsec_status {

   my ($self,$connection_name) = @_;
   my $cmd = 'sudo -s  ipsec status ' .  $connection_name;
   my $status = 0;

   #execute the command
   $self->execute($cmd);

   foreach my $line ( @{ $self->get_stdout() } ) {
        if ( $line =~ m/Security\sassociations\d\()/ ) {
            $status = $1;
        }
    }

    return $status;
}

函数调用:

   $self->{'ipsec_status'} = $self->{'ipsec_obj'}->ipsec_status('connection');
  ('[Startup] ipsec status is  : '  .  $self->{'ipsec_status'} );

实际输出:

INFO    [Startup] ipsec status is  : 0

预期产量:

Security Associations (1 up, 0 connecting)

命令输出:

我需要脚本来捕获预期的输出字符串

Security Associations (1 up, 0 connecting):
      connection[3]: ESTABLISHED 3 seconds ago, 1.1.1.19[1.1.1.19]...10.81.1.50[10.81.1.50]
      connection{3}:  INSTALLED, TUNNEL, ESP in UDP SPIs: cb343e86_i abf6d1f2_o

功能3:

sub ipsec_restart {

    my ($self) = @_;
    my $cmd = 'sudo -s ipsec restart';
    my $restart = 0;

    $self->execute($cmd);

    foreach my $line ( @{ $self->get_stdout() } ) {
     if ( $line =~ /(Starting strongSwan.*IPsec$)/ ) {
          $restart = $1;
          last;
        }
    }

    return $restart;
}

函数调用:

 $self->{'ipsec_restart'} = $self->{'ipsec_obj'}->ipsec_restart();
      ('[Startup] ipsec restart status  is  : '  .  $self->{'ipsec_restart'} );

预期的输出:请参见以下突出显示的文本。 我检查了https://regex101.com/ 我的正则表达式似乎是正确的。 /(开始strongSwan。* IPsec $)/

Starting strongSwan 5.1.2 IPsec


Actual output is  : 0

问题是您使用的是$1 ,只有在您使用的正则表达式中有捕获时才设置。 另外,您应该添加一个last这样一来,您就不会继续搜索匹配的鞋行。 最后,习惯性地将/m/s/x修饰符添加到每个正则表达式匹配项是错误的,无论它们是否有任何区别,并且仅当您使用默认斜杠定界符之外的其他内容时才需要前导m/

第一个功能应包含

for my $line ( @{ $self->get_stdout } ) {
    if ( $line =~ /(strongSwan.*\S)/i ) {
        $version = $1;
        last;
    }
}

第二个功能是相似的,尽管看起来您正在尝试立即将Security associations匹配到一个数字,这与文本中的内容不符。 您也可以使用小a而不是大写字母,如果您还使用/i修饰符,则可以使用。 这将捕获Security Associations直到并包括同一行的最后一个右括号。 那是你需要的吗?

for my $line ( @{ $self->get_stdout } ) {
    if ( $line =~ /(Security\s+Associations.*\))/i ) {
        $status = $1;
        last;
    }
}

对于功能1,假设所有更改都是版本号,我们可以使用

m/(strongSwan.*?) Institute/ms

作为正则表达式。 这将以一种非贪婪的方式匹配从strongSwanInstitute所有内容,并将除Institute之外的所有内容存储在$1

对于函数2,我们将使用未知数据包含在括号中的事实。

 m/(Security associations \(.*?\))/

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM