Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

Problem printing JSON type output

by jonathan.vanderwatt (Initiate)
on Jul 14, 2015 at 11:25 UTC ( #1134684=perlquestion: print w/replies, xml ) Need Help??

jonathan.vanderwatt has asked for the wisdom of the Perl Monks concerning the following question:

Hi friends! I'm no Perl expert but am trying to parse a file for some information which I would like to use to output some JSON formatted text for consumption by Zabbix. The file I'm parsing contains a derivative of the following text:

#Bob monitoring cd /opt/bob-monitor ### version 2 java -jar libs/BobMonitor.jar -xruntime/bob311_2_acc_list.xml -l/tmp/b +ob311/fail.logs -s/tmp/bob311/results.txt 2>&1 java -jar libs/BobMonitor.jar -xruntime/bob411_2_acc_list.xml -l/tmp/b +ob411/fail.logs -s/tmp/bob411/results.txt 2>&1 ### version 3 java -jar libs/BobMonitor.jar -xruntime/bob312_3_acc_list.xml -l/tmp/b +ob312/fail.logs -s/tmp/bob312/results.txt 2>&1 java -jar libs/BobMonitor.jar -xruntime/bob412_3_acc_list.xml -l/tmp/b +ob412/fail.logs -s/tmp/bob412/results.txt 2>&1 ### version 4 java -jar libs/BobMonitor.jar -xruntime/bob313_4_acc_list.xml -l/tmp/b +ob313/fail.logs -s/tmp/bob313/results.txt 2>&1 java -jar libs/BobMonitor.jar -xruntime/bob413_4_acc_list.xml -l/tmp/b +ob413/fail.logs -s/tmp/bob413/results.txt 2>&1 ....
My Perl script looks as follows:
#!/usr/bin/perl print "{"; print " \"data\":\n\t[\n"; my $filename = '/opt/scripts/fester_monitor.sh'; open(my $fh, '<:encoding(UTF-8)', $filename) or die "Could not open file '$filename' $!"; while (my $row = <$fh>) { chomp($row); for($row) { s/^cd.*//; s/^#.*//; ($festerinstance) = m/(fester(\d+))/; print ",\n"; $return = "\t{ \"{#FESTERINSTANCE}\":\"$festerinstance +\"}" unless /(^\s*$|^\,$)/; print $return; } } print "\t]\n"; print "}\n";
The desired output is something like the following:
{ "data": [ { "{#BOBINSTANCE}":"bob311"}, { "{#BOBINSTANCE}":"bob411"}, { "{#BOBINSTANCE}":"bob411"}, { "{#BOBINSTANCE}":"bob411"}, { "{#BOBINSTANCE}":"bob312"}, { "{#BOBINSTANCE}":"bob412"}, { "{#BOBINSTANCE}":"bob412"}, { "{#BOBINSTANCE}":"bob412"}, { "{#BOBINSTANCE}":"bob313"} .... ] }
Yet, I'm getting this:
{ "data": [ , , , , , , { "{#BOBINSTANCE}":"bob311"}, { "{#BOBINSTANCE}":"bob411"}, { "{#BOBINSTANCE}":"bob411"}, { "{#BOBINSTANCE}":"bob411"}, { "{#BOBINSTANCE}":"bob312"}, { "{#BOBINSTANCE}":"bob412"}, { "{#BOBINSTANCE}":"bob412"}, { "{#BOBINSTANCE}":"bob412"}, { "{#BOBINSTANCE}":"bob313"} .... ] }
The issue is the extra commas at the top of the output- which will not be well-formed JSON. Looking at my code, can any one of you perhaps spot something that I may be doing wrong?

Replies are listed 'Best First'.
Re: Problem printing JSON type output
by pme (Prior) on Jul 14, 2015 at 11:44 UTC
    Hi jonathan.vanderwatt

    Welcome to the monastery!

    This little piece of code might help.

    while (my $row = <$fh>) { chomp($row); next if $row =~ /^cd|^#|^$/; # skip lines $row =~ /xruntime\/([a-z0-9]+)_/; # regexp pattern matc +hing with memory () print "\t{ \"{#BOBINSTANCE}\":\"$1\"}\n"; # print memory regist +er $1 }

      Close. Your code gives me the following:

      { "data": [ { "{#BOBINSTANCE}":"bob311"} { "{#BOBINSTANCE}":"bob411"} { "{#BOBINSTANCE}":"bob312"} { "{#BOBINSTANCE}":"bob412"} { "{#BOBINSTANCE}":"bob313"} { "{#BOBINSTANCE}":"bob413"} { "{#BOBINSTANCE}":"bob314"} { "{#BOBINSTANCE}":"bob414"} { "{#BOBINSTANCE}":"bob315"} { "{#BOBINSTANCE}":"bob415"} { "{#BOBINSTANCE}":"bob331"} { "{#BOBINSTANCE}":"bob332"} { "{#BOBINSTANCE}":"bob431"} { "{#BOBINSTANCE}":"bob432"} { "{#BOBINSTANCE}":"bob333"} { "{#BOBINSTANCE}":"bob334"} { "{#BOBINSTANCE}":"bob433"} { "{#BOBINSTANCE}":"bob434"} { "{#BOBINSTANCE}":"bob341"} { "{#BOBINSTANCE}":"bob342"} { "{#BOBINSTANCE}":"bob343"} { "{#BOBINSTANCE}":"bob351"} { "{#BOBINSTANCE}":"bob352"} { "{#BOBINSTANCE}":"bob353"} { "{#BOBINSTANCE}":"bob361"} { "{#BOBINSTANCE}":"bob362"} { "{#BOBINSTANCE}":"bob363"} { "{#BOBINSTANCE}":"bob371"} { "{#BOBINSTANCE}":"bob372"} { "{#BOBINSTANCE}":"bob373"} { "{#BOBINSTANCE}":"bob441"} { "{#BOBINSTANCE}":"bob442"} { "{#BOBINSTANCE}":"bob443"} { "{#BOBINSTANCE}":"bob451"} { "{#BOBINSTANCE}":"bob452"} { "{#BOBINSTANCE}":"bob453"} { "{#BOBINSTANCE}":"bob461"} { "{#BOBINSTANCE}":"bob462"} { "{#BOBINSTANCE}":"bob463"} { "{#BOBINSTANCE}":"bob471"} { "{#BOBINSTANCE}":"bob472"} { "{#BOBINSTANCE}":"bob473"} ] }
      It needs to be:
      { "data": [ { "{#BOBINSTANCE}":"bob311"}, { "{#BOBINSTANCE}":"bob411"}, { "{#BOBINSTANCE}":"bob312"}, { "{#BOBINSTANCE}":"bob412"}, { "{#BOBINSTANCE}":"bob313"}, { "{#BOBINSTANCE}":"bob413"}, { "{#BOBINSTANCE}":"bob314"}, { "{#BOBINSTANCE}":"bob414"}, { "{#BOBINSTANCE}":"bob315"}, { "{#BOBINSTANCE}":"bob415"}, { "{#BOBINSTANCE}":"bob331"}, { "{#BOBINSTANCE}":"bob332"}, { "{#BOBINSTANCE}":"bob431"}, { "{#BOBINSTANCE}":"bob432"}, { "{#BOBINSTANCE}":"bob333"}, { "{#BOBINSTANCE}":"bob334"}, { "{#BOBINSTANCE}":"bob433"}, { "{#BOBINSTANCE}":"bob434"}, { "{#BOBINSTANCE}":"bob341"}, { "{#BOBINSTANCE}":"bob342"}, { "{#BOBINSTANCE}":"bob343"}, { "{#BOBINSTANCE}":"bob351"}, { "{#BOBINSTANCE}":"bob352"}, { "{#BOBINSTANCE}":"bob353"}, { "{#BOBINSTANCE}":"bob361"}, { "{#BOBINSTANCE}":"bob362"}, { "{#BOBINSTANCE}":"bob363"}, { "{#BOBINSTANCE}":"bob371"}, { "{#BOBINSTANCE}":"bob372"}, { "{#BOBINSTANCE}":"bob373"}, { "{#BOBINSTANCE}":"bob441"}, { "{#BOBINSTANCE}":"bob442"}, { "{#BOBINSTANCE}":"bob443"}, { "{#BOBINSTANCE}":"bob451"}, { "{#BOBINSTANCE}":"bob452"}, { "{#BOBINSTANCE}":"bob453"}, { "{#BOBINSTANCE}":"bob461"}, { "{#BOBINSTANCE}":"bob462"}, { "{#BOBINSTANCE}":"bob463"}, { "{#BOBINSTANCE}":"bob471"}, { "{#BOBINSTANCE}":"bob472"}, { "{#BOBINSTANCE}":"bob473"} ] }

        This seems to have solved my problem:

        #!/usr/bin/perl $first=1; print "{"; print " \"data\":\n\t[\n"; my $filename = '/opt/scripts/bob_monitor.sh'; open(my $fh, '<:encoding(UTF-8)', $filename) or die "Could not open file '$filename' $!"; while (my $row = <$fh>) { chomp($row); for($row) { next if $row =~ /^cd|^#|^$|^,/; # skip lines ($bobinstance) = m/(bob(\d+))/; print ",\n" if not $first; $first = 0; $return = "\t{ \"{#BOBINSTANCE}\":\"$bobinstance\"}" u +nless /(^\s*$|^\,$)/; print $return; } } print "\t]\n"; print "}\n";
        Thanks for the help.

Re: Problem printing JSON type output
by ww (Archbishop) on Jul 14, 2015 at 11:36 UTC

    Ln 18?

    Aside: you say the sample data (??) is a "derivative of ...." Do you really mean the actual data is derived (and modified?) from what you've shown us (in which case, show us the actual data) or do you need to rephrase the description?


    ++$anecdote ne $data

      This is what the actual data would like in the text file I am trying to parse.
Re: Problem printing JSON type output
by sundialsvc4 (Abbot) on Jul 14, 2015 at 11:36 UTC

    I would simply use JSON (or JSON::XS), and thereby skate around the entire problem.   If you’ve got a data-structure and you want JSON, or vice-versa, the answer is, “presto!”

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1134684]
Approved by ww
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others scrutinizing the Monastery: (5)
As of 2020-10-30 02:10 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    My favourite web site is:












    Results (277 votes). Check out past polls.

    Notices?