2016-04-11 4 views
1

Ich habe eine Funktion geschrieben, die einen Befehl ausführt. Der Befehl erzeugt einen sehr großen json-Ausgang. Ich möchte, dass die Funktion einen Teil der Ausgabe analysiert und an die aufrufende Funktion zurückgibt.eine große Datei mit Perl json Modul analysieren

Ich möchte, dass die Funktion "lost_packets", "packets" und "lost_percent" von {end} {streams}{udp} in der Ausgabe zurückgibt. (Angezeigt die Werte, die mit Pfeilen zurückgegeben werden) Ich habe decode_json verwendet. Wenn ich den Code ausführe, erhalte ich den folgenden Fehler. "Schlechter Name nach ...". Ich bin mir ziemlich sicher, dass der Befehl ausgeführt wird und ein JSON-Ergebnis erzeugt. Ich glaube, dass ich die Json-Ausgabe nicht richtig analysiere. Kann mir jemand mit dem JSon-Parsing helfen?

 use strict; 
     use warnings; 
     use JSON qw(decode_json); 

    sub parse_json_output { 

     my ($self) = @_; 

     $self->{command}->execute('command goes here'); 

     my @stdout = $self->{command}->stdOut(); 

     my $decoded = decode_json(@stdout); 
     my @output = @{$decoded->{'end'}{'streams'}{'udp'} } ; 
     foreach my $out (@output) { 

     return $out->{"packets"} . "\n"; 

    } 

    } 

Funktionsaufruf:

$ self -> { 'ausführen'} = $ self -> { 'json_obj'} -> parse_json_output();

Befehlsausgabe:

{ 
    "start": { 
     "connected": [{ 
       "socket": 4, 
       "local_host": "9.1.1.2", 
       "local_port": 47669, 
       "remote_host": "8.2.0.2", 
       "remote_port": 12009 
      }], 
     "version": "iperf 3.0.11", 
     "system_info": "Linux nevada-client154 3.13.0-32-generiC#57-Ubuntu SMP Tue Jul 15 03:51:08 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux\n", 
     "timestamp": { 
      "time": "Mon, 11 Apr 2016 22:57:30 GMT", 
      "timesecs": 1460415450 
     }, 
     "connecting_to": { 
      "host": "8.2.0.2", 
      "port": 77545 
     }, 
     "cookie": "nevada-client154.1460415448.675315.5", 
     "test_start": { 
      "protocol": "UDP", 
      "num_streams": 1, 
      "blksize": 576, 
      "omit": 0, 
      "duration": 0, 
      "bytes": 0, 
      "blocks": 4500, 
      "reverse": 0 
     } 
    }, 
    "intervals": [{ 
      "streams": [{ 
        "socket": 4, 
        "start": 0, 
        "end": 4.20106, 
        "seconds": 4.20106, 
        "bytes": 2592000, 
        "bits_per_second": 4.9359e+06, 
        "packets": 4500, 
        "omitted": false 
       }], 
      "sum": { 
       "start": 0, 
       "end": 4.20106, 
       "seconds": 4.20106, 
       "bytes": 2592000, 
       "bits_per_second": 4.9359e+06, 
       "packets": 4500, 
       "omitted": false 
      } 
     }], 
    "end": { 
     "streams": [{ 
       "udp": { 
        "socket": 4, 
        "start": 0, 
        "end": 4.20106, 
        "seconds": 4.20106, 
        "bytes": 2592000, 
        "bits_per_second": 4.9359e+06, 
        "jitter_ms": 0.401183, 
        "lost_packets": 0, ---------> i want this to be returned 
        "packets": 4499, ---------> return 
        "lost_percent": 0 --------- > return 
       } 
      }], 
     "sum": { 
      "start": 0, 
      "end": 4.20106, 
      "seconds": 4.20106, 
      "bytes": 2592000, 
      "bits_per_second": 4.9359e+06, 
      "jitter_ms": 0.401183, 
      "lost_packets": 0, 
      "packets": 4499, 
      "lost_percent": 0 
     }, 
     "cpu_utilization_percent": { 
      "host_total": 1.09968, 
      "host_user": 0.170654, 
      "host_system": 0.928823, 
      "remote_total": 0.00281493, 
      "remote_user": 0.000502673, 
      "remote_system": 0.00224273 
     } 
    }, 
    "server_output_text": "-----------------------------------------------------------\nAccepted connection from 9.1.1.2, port 33836\n[ 5] local 8.2.0.2 port 12009 connected to 9.1.1.2 port 47669\n" 
} 

Antwort

0

Ihre JSON ist falsch formatiert. Ich habe es durch einen Validator (es gibt viele kostenlose online), und es kam mit mehreren Fehlern. Der Validator, den ich benutzt habe, sagte:

Error:Strings should be wrapped in double quotes.[Code 17, Structure 222] 
Error:Invalid characters found.[Code 18, Structure 222] 
Error:Strings should be wrapped in double quotes.[Code 17, Structure 226] 
Error:Invalid characters found.[Code 18, Structure 226] 
Error:Expecting comma or }, not string.[Code 13, Structure 229] 
Error:Strings should be wrapped in double quotes.[Code 17, Structure 229] 

Es sieht aus wie Sie einige doppelte Anführungszeichen irgendwo entlang der Linie haben. Wenn Sie keine Bibliothek verwenden, um den JSON für Ihre Daten zu generieren (was Sie sollten), sollten Sie überprüfen, ob Ihr JSON so oft wie möglich gültig ist - es ist überraschend leicht zu vergessen, einem doppelten Zitat zu entkommen.

0

bedeutet, dass $data->{end}{streams} eine Array-Referenz enthält, die eine Hash-Referenz enthält. So ist die Art und Weise zu bekommen, um das udp Element innerhalb

ist
$decoded->{end}{streams}[0]{udp} 

und die spezifischen Elemente Sie zurückkehren wollen bei

print $decoded->{end}{streams}[0]{udp}{lost_packets}; 
print $decoded->{end}{streams}[0]{udp}{packets}; 
print $decoded->{end}{streams}[0]{udp}{lost_percent}; 
+0

ich folgenden müde. Es scheint nicht zu funktionieren. mein $ decided = decode_json ($ json); mein @output = $ entschlüsselt -> {end} {stream} [0] {udp}; foreach my $ out (@output) { drucken $ out -> {end} {stream} [0] {udp} {lost_packets}; } – nims

+0

Ich bekomme den folgenden Fehler: Verwendung von nicht initialisierten Wert im Druck – nims

+0

Wir falsch geschrieben 'Streams'. – mob