使用perl将json数组转换为csv时出错

时间:2018-11-30 04:26:25

标签: arrays json perl csv

im使用perl脚本将JSON转换为csv。样本json就是这样,

[{"id":100,
"primary-codes":["E0181V00","E0226V00"],
"substitute-codes":["E0181D00","E0226100"],
"fk-id":2294}]

和我用来将其转换为csv的perl代码是

#!/usr/bin/perl
use utf8;
use warnings;
use strict;
use lib '.';
use JSON::PP qw(decode_json);

my $json;
{
local $/;
open my $fh, '<', 'output_array.json' or die $!;
$json = <$fh>;
}

my $perl = decode_json $json;
my $filename = 'sample.csv';
open(my $fh, '>>:encoding(UTF-8)', $filename) or die "Could not open file '$filename' $!";
say $fh 'nk_id,prim_cd,sub_cd,fk_id';

for (@$perl){
my $nk_id = '"' . $_->{"id"} . '"';
my $prim_cd= '"' . $_->{"primary-codes"} . '"';                
my $sub_cd= '"' . $_->{"substitute-codes"} . '"'; 
my $fk_id= '"' . $_->{"fk-id"} . '"';                                  

say $fh "$nk_id," . "$prim_cd," . "$sub_cd," . "$fk_id";
}
close $fh;

我得到的输出是这样的

nk_id,prim_cd,sub_cd,fk_id
100,ARRAY(0x201549f8),ARRAY(0x20154a88),2294

但我希望如此,

100,"E0181V00,E0226V00","E0181D00,E0226100",2294

我尝试使用,

my $prim_cd = '"' . join ",", @{ $perl->[0]{"primary-codes"} } . '"'; 

但是它只返回计数而不是元素。

请帮助我解决这个问题。

谢谢!

1 个答案:

答案 0 :(得分:0)

颠覆您诚实尝试的一个细节是优先。在

my $prim_cd = '"' . join ",", @{ $perl->[0]{"primary-codes"} } . '"';

列表@{ $perl->[0]...}首先与.串联("),并且由于.运算符施加标量上下文,因此使用了列表中的元素数量,得出2"。只有这样join才会做它的事情,“加入”给定列表(它是一个单独的元素,2"

只需添加括号

for (@$perl){
    my $nk_id   = '"' . $_->{"id"} . '"';
    my $prim_cd = '"' . join(',', @{$_->{'primary-codes'}}) . '"';
    my $sub_cd  = '"' . join(',', @{$_->{'substitute-codes'}}) . '"'; 
    my $fk_id   = '"' . $_->{"fk-id"} . '"'; 
    say $fh "$nk_id,$prim_cd,$sub_cd,$fk_id";
}

一些笔记。

  • 您忘记了use feature qw(say);,否则say将无法正常工作。

  • 显示的内容不使用use utf8;,它与源文件本身有关

  • 显示的内容不需要use lib;指定要搜索模块的路径。 (如果那样做的话,它将无助于查找文件。)但是,一旦我们做到了……

  • 我避免使用.,因为它会产生从混乱到直接错误的问题。首先,您是指当前工作目录还是脚本目录?他们不一样。假设您将其用于脚本的目录(不是),则将其替换为

    use FindBin qw($RealBin);
    use lib $RealBin;
    
  • 还可以为文件添加内容

    my $json = do {
        local $/;
        open my $fh, '<', 'output_array.json' or die $!;
        <$fh>;
    };