#/usr/lib/perl
use lib qw(..);
use JSON qw( );
open json_fh, "<$ARGV[0]" or die "Couldn't open file $ARGV[0]!\n";
open csv_fh, ">$ARGV[1]" or die "Couldn't open file $ARGV[1]!\n";
@json_text =<json_fh>;
close json_fh;
foreach $json_text( @json_text )
{
chomp $json_text;
$json = JSON->new;
$data = $json->decode($json_text);
$id=$data->{_id};
@lines=@{$data->{accounts}};
foreach $line ( @lines )
{
$accountNumber = $line->{accountNumber};
$accountType = $line->{accountType};
$cardType = $line->{cardType};
$cardSubType = $line->{cardSubType};
$protectionMethod = $line->{protectionMethod};
$protectionSource = $line->{protectionSource};
$expirationDate = $line->{expirationDate};
$nameOnAccount = $line->{nameOnAccount};
$cardStatus = $line->{cardStatus};
$cardHolderType = $line->{cardHolderType};
$createdBy = $line->{createdBy};
$addressId = $line->{addressId};
$productType = $line->{productType};
$isDefaultAccount = $line->{isDefaultAccount};
#Write to the file in delimited file format
print csv_fh "$id|$accountNumber|$accountType|$cardType|$cardSubType|$protectionMethod|$protectionSource|$expirationDate|$nameOnAccount|$cardStatus|$cardHolderType|$createdBy|$addressId|$productType|$isDefaultAccount\n";
}
}
close csv_fh;
这是我创建的一个perl脚本,用于将JSON文件转换为定界文件(如果元素名称已知)。
任何人都可以帮助我修改代码,以便在元素名称未知的情况下完成此转换。
答案 0 :(得分:2)
假设每个帐户都具有相同的字段(否则就没有意义了),您可以使用以下内容:
my $json_parser = JSON->new;
my @headers;
for my $json_doc (@json_docs) {
my $data = $json_parser->decode($json_doc);
my $id = $data->{_id};
for my $account (@{ $data->{accounts} }) {
if (!@headers) {
@headers = sort keys %$account;
say join "|", 'id', @headers;
}
say join "|", $id, @$account{@headers};
}
}
答案 1 :(得分:0)
您没有提供示例输入文件,所以我猜它是这样的:
{ "accounts": [ { "_id": "1", "accountNumber": "99999", "accountType": "acctTypeA", "cardType": "cardTypeA", "cardSubType": "cardSubTypeA", "protectionMethod": "protectionMethodA", "protectionSource": "protectionSourceA", "expirationDate": "2020-09", "nameOnAccount": "First Last", "cardStatus": "OK", "cardHolderType": "CHTypeA", "createdBy": "userX", "addressId": "444", "productType": "prodTypeA", "isDefaultAccount": "1", "optional": "OptA" } ] }
您非常接近,但是通常整个文件都是JSON记录,因此您不会逐行循环,而是创建一个表示整个文件的数据结构(hashref)(即,您只需要$ json->每个文件解码一次)。
此外,我建议进行一些检查以验证输入,例如缺少字段;如果缺少任何字段,您会看到我死于错误消息。
#!/usr/bin/env perl
use strict;
use lib qw(..);
use JSON qw( );
@ARGV == 2 or die("Infile, Outfile required\n");
open json_fh, "<$ARGV[0]" or die "Couldn't open file $ARGV[0]!\n";
open csv_fh, ">$ARGV[1]" or die "Couldn't open file $ARGV[1]!\n";
my $json_text =<json_fh>;
close json_fh;
my $json = JSON->new->allow_nonref;
my $data = $json->decode($json_text);
my $accounts = $data->{accounts};
my @required = qw(_id accountNumber accountType cardType cardSubType protectionMethod protectionSource expirationDate nameOnAccount cardStatus cardHolderType createdBy addressId productType isDefaultAccount);
my @opt = (); # learn these
my %col; # key => column index
my $lastIndex;
for (my $i=0; $i<=$#required; ++$i) { $lastIndex = $col{$required[$i]} = $i }
print "There are ", $lastIndex+1, " required cols\n";
foreach my $rec ( @$accounts )
{
my @row;
foreach my $key ( keys %$rec )
{
if ( ! exists($col{$key}) ) {
# new (optional) key
push @opt, $key;
$col{$key} = ++$lastIndex;
print "New col: $key (col ", $lastIndex+1, ")\n";
}
$row[$col{$key}] = $rec->{$key};
}
# check for all required
for (my $i=0; $i<=$#required; ++$i) {
defined($row[$i]) or die("Missing: $required[$i]\n");
}
#Write to the file in delimited file format
print csv_fh join("|", @row), "\n";
}
close csv_fh;