我有一个JSON文件,其中包含客户和日期列表。
该文件如下所示:
{
"Customers": [
{
"Customer": "Customer Name Here",
"Company": "Super Coffee",
"First Name": "First Name Here",
"Main Phone": "777-777-7777",
"Fax": "777-777-7777",
"Bill to 1": "Billing Address One",
"Bill to 2": "Billing Address Two",
"Bill to 3": "Billing Address Three",
"Ship to 1": "Shipping Address One",
"Ship to 2": "Shipping Address Two",
"Ship to 3": "Shipping Address Three",
"Customer Type": "Dealer/Retail"
},
{
"Customer": "Customer Name Here",
"Company": "Turtle Mountain Welding",
"First Name": "First Name Here",
"Main Phone": "777-777-7777",
"Fax": "777-777-7777",
"Bill to 1": "Billing Address One",
"Bill to 2": "Billing Address Two",
"Bill to 3": "Billing Address Three",
"Ship to 1": "Shipping Address One",
"Ship to 2": "Shipping Address Two",
"Ship to 3": "Shipping Address Three",
"Customer Type": "Dealer/Retail"
},
{
"Customer": "Customer Name Here",
"Company": "Mountain Equipment Coop",
"First Name": "First Name Here",
"Main Phone": "777-777-7777",
"Fax": "777-777-7777",
"Bill to 1": "Billing Address One",
"Bill to 2": "Billing Address Two",
"Bill to 3": "Billing Address Three",
"Ship to 1": "Shipping Address One",
"Ship to 2": "Shipping Address Two",
"Ship to 3": "Shipping Address Three",
"Customer Type": "Dealer/Retail"
},
{
"Customer": "Customer Name Here",
"Company": "Best Soup Inc.",
"First Name": "First Name Here",
"Main Phone": "777-777-7777",
"Fax": "777-777-7777",
"Bill to 1": "Billing Address One",
"Bill to 2": "Billing Address Two",
"Bill to 3": "Billing Address Three",
"Ship to 1": "Shipping Address One",
"Ship to 2": "Shipping Address Two",
"Ship to 3": "Shipping Address Three",
"Customer Type": "Dealer/Retail"
}
]
}
我需要能够逐块地从文件中提取数据,而不是逐行提取。
我习惯逐行解析文件以获取数据,但是使用JSON,我需要以某种方式逐块读取它(或者更准确地说,逐个对象读取?)。我需要通过每个客户的括号内的内容来阅读它。这样我就可以编写一个脚本来提取我需要的数据,并从中构建一个CSV文件。
例如:
i="1"
for file in *.json; do
customername=$(jsonblock$i:customername);
customerAddress=$(jsonblock$i:customeraddress);
etc...
i=$[i+1]
done
我理解在逐行读取文件时如何完成此操作,但是如何读取每个JSON块,就好像它是一行一样呢?
答案 0 :(得分:4)
对于上面的JSON(由于提供的数据无效而被修改),以下脚本将解析并打印每个块的"Company:"
部分:
#!/usr/bin/env perl
use JSON;
use IO::All;
use v5.16;
my $data < io 'Our_Customers.json';
my $customers_list = decode_json($data)->{"Customers"};
for my $customer (@$customers_list) {
say $customer->{"Company"} ;
}
<强>输出强>:
Super Coffee
Turtle Mountain Welding
Mountain Equipment Coop
Best Soup Inc.
该脚本使用IO::All
和JSON
来读取和解析(decode_json
)文件。
在此示例中,JSON数据只是映射到Perl数据结构(Array of Hashes),它与JSON数据完全对应。然后,我们可以访问每个数组元素(, 数组中的每个哈希),然后通过键名访问哈希内的数据。 Perl具有非常灵活的数据修改和访问功能,这使得使用JSON数据非常愉快。
每个数据块的键来自JSON文件的等效部分。如果我们从数组中移出一个元素,它将是一个哈希,我们访问可以看到元素的keys
和values
,如下所示:
say for keys shift $customers_list ;
Customer Type
First Name
Bill to 2
Main Phone
...
使用您在$element->{"key"}
循环中看到的for
语法访问每个键的值。
最好在将JSON数据发布到SO - JSON Lint之前对其进行验证,类似的服务可以为此提供帮助。
答案 1 :(得分:1)
使用perl和JSON库可以逐步解析JSON列表中的每个项目,但是你需要使用json以使它实际上不是json,而是一个没有用逗号分隔的json对象列表。
<!-- GET THE LIBRARIES (YOU SHOULD ALREADY HAVE THEM) -->
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/jquery-ui.min.js"></script>
<script src="http://ajax.aspnetcdn.com/ajax/jquery.validate/1.11.1/jquery.validate.js"></script>
<script>
$(document).ready(function() {
$("#confirm").click(function() {
$.ajax({
// This is where you need the right path to the new php file
url:'/path/to/new.php',
type: 'post',
data: $("#orderform").serialize(),
success: function(response) {
$("#final").html(response);
}
});
});
});
</script>
对于customers.json(不再是json):
#!/usr/bin/perl
use strict;
use warnings;
use feature qw(say);
use JSON;
my $json = JSON->new;
while (<>) {
my $obj_or_undef = eval { $json->incr_parse( $_ ); };
# Wait until its found a whole object
if (ref $obj_or_undef) {
say join ",", map {$obj_or_undef->{$_}} sort keys %$obj_or_undef;
}
}
运行:
{
"some key" : "some value"
} {
"other key" : "other value"
}
答案 2 :(得分:1)
如果您的目的只是以CSV格式打印JSON数据,那么您提出的问题是错误的。您应该解析整个JSON文档并逐项处理Customers
数组。
使用Perl的JSON
和Text::CSV
模块,看起来像这样
use strict;
use warnings;
use JSON 'from_json';
use Text::CSV ();
my @columns = (
'Bill to 1', 'Bill to 2', 'Bill to 3', 'Company',
'Customer', 'Customer Type', 'Fax', 'First Name',
'Main Phone', 'Ship to 1', 'Ship to 2', 'Ship to 3',
);
my $out_fh = \*STDOUT;
my $json_file = 'customers.json';
my $data = do {
open my $fh, '<', $json_file or die qq{Unable to open "$json_file" for input: $!};
local $/;
from_json(<$fh>);
};
my $customers = $data->{Customers};
my $csv = Text::CSV->new({ eol => $/ });
$csv->print($out_fh, \@columns);
for my $customer ( @$customers ) {
$csv->print($out_fh, [ @{$customer}{@columns} ]);
}
<强>输出强>
"Bill to 1","Bill to 2","Bill to 3",Company,Customer,"Customer Type",Fax,"First Name","Main Phone","Ship to 1","Ship to 2","Ship to 3"
"Billing Address One","Billing Address Two","Billing Address Three","Super Coffee","Customer Name Here",Dealer/Retail,777-777-7777,"First Name Here",777-777-7777,"Shipping Address One","Shipping Address Two","Shipping Address Three"
"Billing Address One","Billing Address Two","Billing Address Three","Turtle Mountain Welding","Customer Name Here",Dealer/Retail,777-777-7777,"First Name Here",777-777-7777,"Shipping Address One","Shipping Address Two","Shipping Address Three"
"Billing Address One","Billing Address Two","Billing Address Three","Mountain Equipment Coop","Customer Name Here",Dealer/Retail,777-777-7777,"First Name Here",777-777-7777,"Shipping Address One","Shipping Address Two","Shipping Address Three"
"Billing Address One","Billing Address Two","Billing Address Three","Best Soup Inc.","Customer Name Here",Dealer/Retail,777-777-7777,"First Name Here",777-777-7777,"Shipping Address One","Shipping Address Two","Shipping Address Three"