使用Perl脚本将JSON文件转换为CSV

bpsygsoo  于 12个月前  发布在  Perl
关注(0)|答案(2)|浏览(92)

我尝试用Perl脚本将JSON文件转换为CSV:

use strict;
use warnings;
use Text::CSV_XS;
use JSON::MaybeXS;
use FileHandle ;
use IO::Handle;

local( $/, *FH ) ;

open( FH, '<', 'out_spot.json' ) or die "Can't open out_spot.json: $!";
my $text = <FH>;

my $data = decode_json($text);

my $csv = Text::CSV_XS->new({auto_diag=>2,binary=>1, eol=>"\n", always_quote=>1 });

open(my $OUT, ">:encoding(utf8)", "out_spot.csv") or die "out_spot.csv: $!";
my @fields = qw/    spotterId   spotterName payloadType batteryVoltage  batteryPower    solarVoltage    humidity    track   latitude    longitude   timestamp   waves   significantWaveHeight   peakPeriod  meanPeriod  peakDirection   peakDirectionalSpread   meanDirection   meanDirectionalSpread   timestamp   latitude    longitude   frequencyData   frequency   df  varianceDensity direction   directionalSpread   timestamp   latitude    longitude /;
$csv->print($OUT, \@fields);
for my $datapoint ( @{ $data->{data} } ) {
   $csv->print($OUT, [ map {$datapoint->{$_}} @fields ]);
}

close $OUT;

JSON文件out_spot.json:

{
   "data" : {
       "spotterId" : "SPOT-30344R",
       "spotterName" : "",
       "payloadType" : "full",
       "batteryVoltage" : 4.01,
       "batteryPower" : -0.15,
       "solarVoltage" : 0.22,
       "humidity" : 46.4,
       "track" : [{
           "latitude" : -28.4223833,
           "longitude" : -37.5605,
           "timestamp" : "2023-09-12T06:28:31.000Z"
       }, {
           "latitude" : -28.4279833,
           "longitude" : -37.56795,
           "timestamp" : "2023-09-12T06:58:31.000Z"
       }],
    .....
}

所需CSV输出:
| spotterId| spotterName| payloadType|电池电压|
| --|--|--|--|
| SPOT-30344R||充分|4.01|
| 纬度|经度|
| --|--|
| -28.4223833 | -37.5605 |
| -28.4279833 | -37.56795 |
脚本没有给予我任何错误,但CSV文件没有数据,它只包含标题。
我的代码有什么问题?

nbysray5

nbysray51#

我已经使你的JSON示例更具可读性(不客气,但请考虑将来自己做),很明显,你的JSON不包含Datapoints键,所以我不确定为什么你的代码需要这个键。
您的JSON示例不准确,或者您的代码与输入不匹配。
此外,还不清楚数据如何Map到简单的CSV文件。在data记录中有多个track记录。也许您可以编辑您的问题,以添加来自示例输入的预期输出。

ehxuflar

ehxuflar2#

看看这是否能让你开始:

use strict;
    use 5.010;
    use JSON::PP;

    our $hdr= 'spotterId,spotterName,payloadType,batteryVoltage,batteryPower,solarVoltage,humidity,latitude,longitude';
    our $q = '"';

    my $data = qx/cat data.json/;
    my $decoded_json = decode_json $data;

    my $o1 = $decoded_json->{data}->{spotterId};
    my $o2 = $decoded_json->{data}->{spotterName};
    my $o3 = $decoded_json->{data}->{payloadType};
    my $o4 = $decoded_json->{data}->{batteryVoltage};
    my $o5 = $decoded_json->{data}->{solarVoltage};
    my $o6 = $decoded_json->{data}->{humidity};

    my @track= ();
    my $track = ($decoded_json->{data}->{track});
    if ($track) {
      @track= @{$track};
    }

    my @lat=();
    my @lng=();
    foreach (@track) {
      push(@lat,$_->{latitude});
      push(@lng,$_->{longitude});
    }
    my $o7 = join ":", @lat; # change to newline I preferred colon
    my $o8 = join ":", @lng;

    say $hdr;
    say "$q$o1$q,$q$o2$q,$q$o3$q$o4$q,$q$o5$q,$q$o6$q,$q$o7$q,$q$o8$q";

相关问题