从perl代码

时间:2017-04-19 07:22:51

标签: regex perl ibm-mq

我的perl代码有问题,我编写的代码假设从MQ命令dis ql(*) all获取一些信息, 下面是上面命令的输出示例之一

    AMQ8409: Display Queue details.
   QUEUE(XXX.DATATYPE.NETSTATVM)           TYPE(QLOCAL)
   ACCTQ(QMGR)                             ALTDATE(2016-08-01)
   ALTTIME(18.33.19)                       BOQNAME( )
   BOTHRESH(0)                             CLUSNL( )
   CLUSTER( )                              CLCHNAME( )
   CLWLPRTY(0)                             CLWLRANK(0)
   CLWLUSEQ(QMGR)                          CRDATE(2016-08-01)
   CRTIME(18.33.19)                        CURDEPTH(0)
   CUSTOM( )                               DEFBIND(OPEN)
   DEFPRTY(0)                              DEFPSIST(YES)
   DEFPRESP(SYNC)                          DEFREADA(NO)
   DEFSOPT(SHARED)                         DEFTYPE(PREDEFINED)
   DESCR(Queue for  XXX.DataType.netstatvm)
   DISTL(NO)                               GET(ENABLED)
   HARDENBO                                INITQ( )
   IPPROCS(1)                              MAXDEPTH(20000)
   MAXMSGL(33554432)                       MONQ(QMGR)
   MSGDLVSQ(PRIORITY)                      NOTRIGGER
   NPMCLASS(NORMAL)                        OPPROCS(0)
   PROCESS( )                              PUT(ENABLED)
   PROPCTL(COMPAT)                         QDEPTHHI(80)
   QDEPTHLO(20)                            QDPHIEV(DISABLED)
   QDPLOEV(DISABLED)                       QDPMAXEV(ENABLED)
   QSVCIEV(NONE)                           QSVCINT(999999999)
   RETINTVL(999999999)                     SCOPE(QMGR)
   SHARE                                   STATQ(QMGR)
   TRIGDATA( )                             TRIGDPTH(1)
   TRIGMPRI(0)                             TRIGTYPE(FIRST)
   USAGE(NORMAL)                        

上面的输出是从MQ中的一个队列中获取的,而不是命令运行的all队列。

从上面,我想从QUEUECURDEPTHMAXDEPTH中提取值,如下所示: -

QUEUE(XXX.DATATYPE.NETSTATVM)
CURDEPTH(0)
MAXDEPTH(20000)

所以,我编写了一个perl代码来获取QUEUECURDEPTHMAXDEPTH的值,下面是我的代码,

my $qm = XXX;

open (CHS_OUT, "echo 'dis ql(*) all'|runmqsc $qm|");

while (<CHS_OUT>) {
    if ( /QUEUE\(/ ){
        my $QueueName =~ /QUEUE/(/\S+)/g;
    }
    if ( /CURDEPTH\(/ ){
        my $CurDepth =~ s/\D//g;
        chomp $CurDepth;
        print "$CurDepth \n";
    }
    if ( /MAXDEPTH\(/ ){
        my $MaxDepth =~ s/\D//g;
        chomp $MaxDepth;
        print "$MaxDepth \n";
    }
}

输出假设如下,

XXX.DATATYPE.NETSTATVM
0
20000

但是,我收到了多个错误,无法提取所有这三个信息,其中一个错误如下,

  

在mq_test.pl第26行第7361行使用未初始化的值$ MaxDepth替换(s ///)。
      在mq_test.pl第27行第7361行的标量清零中使用未初始化的值$ MaxDepth。
      在连接(。)中使用未初始化的值$ MaxDepth或在mq_test.pl第28行,第7361行使用字符串。

这让我感到困惑,因为我已经对此代码进行了多次更改,但仍未成功。

3 个答案:

答案 0 :(得分:2)

您可以使用以下正则表达式

(?:QUEUE|CURDEPTH|MAXDEPTH)\(\K[^()]+

a demo on regex101.com

<小时/> 那是

(?:QUEUE|CURDEPTH|MAXDEPTH) # one of the alternatives
\(                          # an opening bracket
\K                          # "forget" everything
[^()]+                      # not (), at least once

<小时/> 在Perl中,这将是:

my @matches = $str =~ /(?:QUEUE|CURDEPTH|MAXDEPTH)\(\K[^()]+/g;
print "@matches\n";
# XXX.DATATYPE.NETSTATVM
# 0
# 20000

答案 1 :(得分:1)

=~是绑定运算符。它将左手边的弦绑定到右手边的比赛。但是你在LHS上有my $variable - 所以字符串是空的。你想要的是匹配隐含变量,并可能存储匹配的一部分。这是通过列表上下文中的正常分配完成的:

#!/usr/bin/perl
use warnings;
use strict;

while (<>) {
    if ( /QUEUE\(/ ) {
        my ($QueueName) = /QUEUE\((\S+)\)/;
        print "QN: $QueueName\n";
    }
    if ( /CURDEPTH\(/ ) {
        my ($CurDepth) = /CURDEPTH\((\d+)/;
        print "CD: $CurDepth\n";
    }
    if ( /MAXDEPTH\(/ ) {
        my ($MaxDepth) = /MAXDEPTH\((\d+)/;
        print "MD: $MaxDepth\n";
    }
}

您也可以将所有正则表达式合并为一个,并使用哈希值来存储括号前的单词键入的值:

#!/usr/bin/perl
use warnings;
use strict;

my %info;
while (<>) {
    if (my ($key, $value)
        = / ( QUEUE | CURDEPTH | MAXDEPTH ) \( ( [^)]+ ) /x
    ) {
        $info{$key} = $value;
    }
}

for my $key (keys %info) {
    print "$key: $info{$key}\n";
}

答案 2 :(得分:1)

我使用以下内容与awk做类似的事情:

echo "DIS QL(*) CURDEPTH MAXDEPTH"|runmqsc $qm | grep -o '^\w\+:\|\w\+[(][^)]\+[)]' | awk -F '[()]' -v OFS='\n' 'function printValues() { if ("QUEUE" in p) { print p["QUEUE"], p["CURDEPTH"], p["MAXDEPTH"], "" } } /^\w+:/ { printValues(); delete p; next } { p[$1] = $2 } END { printValues() }'

输出看起来像这样:

XXX.DATATYPE.NETSTATVM
0
20000

YYY.DATATYPE.NETSTATVM
50
10000