?
Solved

Parse query results and then give output on one line.

Posted on 2006-10-26
12
Medium Priority
?
435 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
Industry Leaders: 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 800 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 1200 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

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!

Question has a verified solution.

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

I have been pestered over the years to produce and distribute regular data extracts, and often the request have explicitly requested the data be emailed as an Excel attachement; specifically Excel, as it appears: CSV files confuse (no Red or Green h…
In the distant past (last year) I hacked together a little toy that would allow a couple of Manager types to query, preview, and extract data from a number of MongoDB instances, to their tool of choice: Excel (http://dilbert.com/strips/comic/2007-08…
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
Suggested Courses

743 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