Solved

Parse query results and then give output on one line.

Posted on 2006-10-26
12
432 Views
Last Modified: 2012-06-22
I have this:

---------
#!/usr/bin/perl

$CheckNTPath='/etc/nagios/libexec';

my $output = `$CheckNTPath/check_nt2 -H $ARGV[0] -p 1248 -v WMICHECK -l "MicrosoftDNS^SELECT name,value FROM MicrosoftDNS_Statistic where CollectionId='4'`;

---------------
Which outputs this:

instance of MicrosoftDNS_Statistic
{
        Name = "ALL queries";
        Value = 16;
};

instance of MicrosoftDNS_Statistic
{
        Name = "IXFR queries";
        Value = 0;
};

instance of MicrosoftDNS_Statistic
{
        Name = "AXFR queries";
        Value = 0;
};

instance of MicrosoftDNS_Statistic
{
        Name = "Other queries";
        Value = 63223;
};

--------------------

I would like to take that query output and extract the Values and Names so that it looks like this:

ALL:0 IXFR:0 AXFR:0 Other:0


Thanks for any help.. i am a wee bit of a novice at perl but i do know ASP inside and out... i just need someone to help me connect the dots when parsing.
0
Comment
Question by:Brent
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 4
  • 2
12 Comments
 
LVL 19

Expert Comment

by:Kim Ryan
ID: 17815941
This should give you what you want. Did you mean all 0s or did you want to capture the Value = portion (assumed u did)


my %names;
my $curr_name;
my $counter;
while ( <DATA> )
{
    # match pattern Name = "ALL queries"; saving the ALL portion
    $_ =~ /Name = "(\w+) / and $curr_name = $1;
    # if Value found, rtain number
    if ( $_ =~ /Value = (\d+)/ )
    {
        $counter++;
        # store in a hash, and use counter to retian original order
        $names{"$counter\_$curr_name"} = $1;
    }
}

# unroll hash
foreach my $key ( sort keys %names )
{
    my $name;
    # key is 1_ALL etc, strip of the number part
    (undef,$name) =  split(/_/,$key);
    # print just the ALL word plus its value then a space
    print("$name:$names{$key} ");
}
print "\n";

__DATA__
instance of MicrosoftDNS_Statistic
{
        Name = "ALL queries";
        Value = 16;
};

instance of MicrosoftDNS_Statistic
{
        Name = "IXFR queries";
        Value = 0;
};
instance of MicrosoftDNS_Statistic
{
        Name = "AXFR queries";
        Value = 0;
};

instance of MicrosoftDNS_Statistic
{
        Name = "Other queries";
        Value = 63223;
};
0
 
LVL 84

Expert Comment

by:ozo
ID: 17815956
printf(("%s: %s "x4)."\n",$output=~/"(ALL|IXFR|AXFR|Other)\b.*?\bValue\s*=\s*(\d+)/gs);
0
 
LVL 8

Author Comment

by:Brent
ID: 17815984
i wanted to capture the data.. sorry i should of used the values in the output.
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 19

Assisted Solution

by:Kim Ryan
Kim Ryan earned 200 total points
ID: 17816034
OK, same code put getting the data from your $output string

my %names;
my $curr_name;
my $counter;
my @lines = split("\n",$output);

for my $line ( @lines )
{
    print ">>$line<<\n";
    # match pattern Name = "ALL queries"; saving the ALL portion
    $line =~ /Name = "(\w+) / and $curr_name = $1;
    # if Value found, retain number
    if ( $line =~ /Value = (\d+)/ )
    {
        $counter++;
        # store in a hash, and use counter to retian original order
        $names{"$counter\_$curr_name"} = $1;
    }
}

# unroll hash
foreach my $key ( sort keys %names )
{
    my $name;
    # key is 1_ALL etc, strip of the number part
    (undef,$name) =  split(/_/,$key);
    # print just the ALL word plus its value then a space
    print("$name:$names{$key} ");
}
print "\n";
0
 
LVL 8

Author Comment

by:Brent
ID: 17816051
teraplane, i like your setup but i cannot get the data in there.. how do i put the $output result inside the while statement?

ozo, your solution worked perfectly, does it allow for other name/value pairs?  The reason i ask is because there are about 15 responses that come back from the query that look like those results.. i just cut them off to save space.
0
 
LVL 84

Accepted Solution

by:
ozo earned 300 total points
ID: 17816063
print "$1: $2 " while $output =~/Name\s*=\s*"(\w+)\b.*?\bValue\s*=\s*(\d+)/gs;
0
 
LVL 8

Author Comment

by:Brent
ID: 17816065
teraplane.. two issues:

1. It prints the data query which i dont need and makes the output very long
2. The results are out of order

>><<
>>instance of MicrosoftDNS_Statistic<<
>>{<<
>>      Name = "Total queries";<<
>>      Value = 423156;<<
>>};<<
>><<
>>instance of MicrosoftDNS_Statistic<<
>>{<<
>>      Name = "Notify queries";<<
>>      Value = 0;<<
>>};<<
>><<
>>instance of MicrosoftDNS_Statistic<<
>>{<<
>>      Name = "Update queries";<<
>>      Value = 475;<<
>>};<<
>><<
>>instance of MicrosoftDNS_Statistic<<
>>{<<
>>      Name = "TKeyNego queries";<<
>>      Value = 54;<<
>>};<<
>><<
>>instance of MicrosoftDNS_Statistic<<
>>{<<
>>      Name = "Standard queries";<<
>>      Value = 422627;<<
>>};<<
>><<
>>instance of MicrosoftDNS_Statistic<<
>>{<<
>>      Name = "A queries";<<
>>      Value = 331018;<<
>>};<<
>><<
>>instance of MicrosoftDNS_Statistic<<
>>{<<
>>      Name = "NS queries";<<
>>      Value = 6;<<
>>};<<
>><<
>>instance of MicrosoftDNS_Statistic<<
>>{<<
>>      Name = "SOA queries";<<
>>      Value = 430;<<
>>};<<
>><<
>>instance of MicrosoftDNS_Statistic<<
>>{<<
>>      Name = "MX queries";<<
>>      Value = 1037;<<
>>};<<
>><<
>>instance of MicrosoftDNS_Statistic<<
>>{<<
>>      Name = "PTR queries";<<
>>      Value = 24374;<<
>>};<<
>><<
>>instance of MicrosoftDNS_Statistic<<
>>{<<
>>      Name = "SRV queries";<<
>>      Value = 1003;<<
>>};<<
>><<
>>instance of MicrosoftDNS_Statistic<<
>>{<<
>>      Name = "ALL queries";<<
>>      Value = 16;<<
>>};<<
>><<
>>instance of MicrosoftDNS_Statistic<<
>>{<<
>>      Name = "IXFR queries";<<
>>      Value = 0;<<
>>};<<
>><<
>>instance of MicrosoftDNS_Statistic<<
>>{<<
>>      Name = "AXFR queries";<<
>>      Value = 0;<<
>>};<<
>><<
>>instance of MicrosoftDNS_Statistic<<
>>{<<
>>      Name = "Other queries";<<
>>      Value = 64743;<<
>>};<<
PTR:24374 SRV:1003 ALL:16 IXFR:0 AXFR:0 Other:64743 Total:423156 Notify:0 Update:475 TKeyNego:54 Standard:422627 A:331018 NS:6 SOA:430 MX:1037
0
 
LVL 8

Author Comment

by:Brent
ID: 17816076
wow.. oro.. simplicy.. nice.. only have one issue with yours.  There is a space between the colon and the value:

Total: 423286 Notify: 0 Update: 475 TKeyNego: 54 Standard: 422757 A: 331128 NS: 6 SOA: 430 MX: 1037 PTR: 24378 SRV: 1004 ALL: 16 IXFR: 0 AXFR: 0 Other: 64758
0
 
LVL 19

Expert Comment

by:Kim Ryan
ID: 17816079
I left a debug step in by mistake, remove this line
print ">>$line<<\n";

This should be order of occurence, what order were u expecting.
0
 
LVL 8

Author Comment

by:Brent
ID: 17816086
ok nevermind oro, fixed the space... :)

0
 
LVL 8

Author Comment

by:Brent
ID: 17816124
Thanks guys for your quick and most excellent answers!  I split the points because you both answered/gave a solution, but i awarded 300 to oro because of his very efficient solution.

0
 
LVL 19

Expert Comment

by:Kim Ryan
ID: 17816147
Realized no need for hash, so can simplify a lot

my @lines = split("\n",$output);
for my $line ( @lines )
{
    # match pattern Name = "ALL queries"; saving the ALL portion
    $line =~ /Name = "(\w+) / and print "$1:";
    # if Value found, print number
    $line =~ /Value = (\d+)/  and print "$1 ";
}
print "\n";

The problem with the following style of code is that it is very hard to decipher it's intent. If you come along in a few weeks and try to understand what it is doing,  it's not going to be easy.
 print "$1: $2 " while $output =~/Name\s*=\s*"(\w+)\b.*?\bValue\s*=\s*(\d+)/gs;
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

I've just discovered very important differences between Windows an Unix formats in Perl,at least 5.xx.. MOST IMPORTANT: Use Unix file format while saving Your script. otherwise it will have ^M s or smth likely weird in the EOL, Then DO NOT use m…
Many time we need to work with multiple files all together. If its windows system then we can use some GUI based editor to accomplish our task. But what if you are on putty or have only CLI(Command Line Interface) as an option to  edit your files. I…
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
Six Sigma Control Plans

691 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question