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 (Monsignor) 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 locked_user 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!”