我编写了一个执行命令的函数。该命令产生一个非常大的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"
}
答案 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};