2016-04-11 14 views
1

コマンドを実行する関数を記述しました。コマンドは非常に大きなjson出力を生成します。私は、関数が出力の一部を解析し、それを呼び出し関数に返すようにします。perl jsonモジュールを使用して大きなファイルを解析する

出力で{end} {streams}{udp}から "lost_packets"、 "packets"、 "lost_percent"を返すようにしたい(矢印で返される値を示しています)、私はdecode_jsonを使用しました。コードを実行すると、次のエラーが発生します。 "悪い名前の後..."。コマンドが実行され、json結果が生成されることは間違いありません。私はjsonの出力を正しく解析していないと信じています。誰かがjsonの解析で私を助けることができますか?

 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"; 

    } 

    } 

関数呼び出し:

$自己 - > { 'を実行'} = $自己 - > { 'json_obj'} - > parse_json_output();

コマンドの出力:

{ 
    "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" 
} 

答えて

0

あなたのJSONは不正な形式です。私はバリデーター(多くの無料オンラインのものがあります)を通してそれを実行し、それは複数のエラーを思い付いた。私が使用したバリデーターは次のように言っています:

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] 

行のどこかに二重引用符がないようです。 JSONをデータ用に生成するためにライブラリを使用していない場合は、できるだけ有効なJSONを検証する必要があります。二重引用符を逃すのを忘れてしまうのは驚くほど簡単です。

0
"streams": [{ ... }], 

は、$data->{end}{streams}がハッシュリファレンスを保持する配列参照を保持することを意味します。だから、内部udp要素を取得する方法は

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

であり、あなたが返すようにしたい特定の要素は

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

であるI疲れ以下。それは動作していないようです。 my $ decoded = decode_json($ json); my @output = $ {end} {stream} [0] {udp}; foreach my $ out(@output){ print $ out - > {end} {stream} [0] {udp} {lost_packets}; } – nims

+0

次のエラーが表示されます。印刷時に初期化されていない値を使用する – nims

+0

'streams'のスペルが間違っています。 – mob

関連する問題