首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >用于捕获部分命令输出的Perl正则表达式

用于捕获部分命令输出的Perl正则表达式
EN

Stack Overflow用户
提问于 2015-04-09 20:28:32
回答 2查看 230关注 0票数 0

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

我在一个库中编写了两个函数,并从我的测试脚本中调用这些函数。我对正则表达式有些问题。有人能帮我处理正则表达式吗?

职能1:

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

}

函数调用:

代码语言:javascript
运行
复制
$self->{'ipsec_version'} = $self->{'ipsec_obj'}->ipsec_version();
INFO('[Startup] ipsec version is  : ' .  $self->{'ipsec_version'} );

实际产出:

代码语言:javascript
运行
复制
Use of uninitialized value in concatenation (.) or string at ... line 37.
     ipsec version is  : 

预期产出:

代码语言:javascript
运行
复制
strongSwan U5.1.2/K3.16.0-30-generic

命令输出:

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

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

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

函数调用:

代码语言:javascript
运行
复制
   $self->{'ipsec_status'} = $self->{'ipsec_obj'}->ipsec_status('connection');
  ('[Startup] ipsec status is  : '  .  $self->{'ipsec_status'} );

实际产出:

代码语言:javascript
运行
复制
INFO    [Startup] ipsec status is  : 0

预期产出:

代码语言:javascript
运行
复制
Security Associations (1 up, 0 connecting)

命令输出:

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

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

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

函数调用:

代码语言:javascript
运行
复制
 $self->{'ipsec_restart'} = $self->{'ipsec_obj'}->ipsec_restart();
      ('[Startup] ipsec restart status  is  : '  .  $self->{'ipsec_restart'} );

预期输出:见下面突出显示的文本。我登记了https://regex101.com/。我的判断似乎是正确的。/(启动强天鹅。*IPsec$)/

代码语言:javascript
运行
复制
Starting strongSwan 5.1.2 IPsec


Actual output is  : 0
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-04-09 20:53:49

问题是,您使用的是$1,只有在您使用的正则表达式中有捕获时,才会设置它。另外,您应该添加一个last,这样一旦找到匹配的行,就不会继续搜索。最后,习惯于将/m/s/x修饰符添加到每个正则表达式匹配中是错误的,而不管它们是否有任何区别,只有在使用默认斜杠分隔符以外的东西时,才需要使用前导m/

第一个函数应该包含

代码语言:javascript
运行
复制
for my $line ( @{ $self->get_stdout } ) {
    if ( $line =~ /(strongSwan.*\S)/i ) {
        $version = $1;
        last;
    }
}

第二个函数类似,尽管看起来您试图匹配Security associations,后面紧跟一个数字,这不是文本中的内容。您还有一个小的a而不是大写,如果您也使用/i修饰符的话,这是很好的。这捕获到并包括同一行上的最后一个结束括号的Security Associations。这就是你需要的吗?

代码语言:javascript
运行
复制
for my $line ( @{ $self->get_stdout } ) {
    if ( $line =~ /(Security\s+Associations.*\))/i ) {
        $status = $1;
        last;
    }
}
票数 0
EN

Stack Overflow用户

发布于 2015-04-09 21:00:48

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

代码语言:javascript
运行
复制
m/(strongSwan.*?) Institute/ms

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

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

代码语言:javascript
运行
复制
 m/(Security associations \(.*?\))/
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29548351

复制
相关文章

相似问题

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