Как преобразовать файл JSON в файл с разделителями, используя Perl. - PullRequest
0 голосов
/ 27 сентября 2018
#/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 в файл с разделителями, если имена элементов известны.

Может кто-нибудь помочь мне изменить код так, чтобы этопреобразование может быть сделано, когда имена элементов неизвестны.

Ответы [ 2 ]

0 голосов
/ 27 сентября 2018

Предполагая, что все учетные записи имеют одинаковые поля - в противном случае это не имеет смысла - вы можете использовать следующее:

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};
   }
}
0 голосов
/ 27 сентября 2018

Вы не предоставили пример входного файла, поэтому я предполагаю, что он выглядит примерно так:

{ "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-> decode для каждого файла).

Кроме того, япредложил бы некоторые проверки для подтверждения ввода, такие как пропущенные поля;Вы можете видеть, что я умираю с сообщением об ошибке, если какое-либо поле отсутствует.

#!/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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...