使用perl json模块解析大文件

时间:2016-04-11 23:05:14

标签: perl perl-module

我编写了一个执行命令的函数。该命令产生一个非常大的json输出。我希望函数解析输出的一部分并将其返回给调用函数。

我希望函数返回" lost_packets" ,"数据包"和" lost_percent"来自输出中的{end} {streams}{udp}。(表示要用箭头返回的值)我使用了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";

    }

  }

函数调用:

$ self-> {'执行'} = $ self-> {' 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"
}

2 个答案:

答案 0 :(得分: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是否有效 - 它很容易忘记逃避双重报价。

答案 1 :(得分: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};