我有一个大型JSON对象文件(超过12000行),如下所示:
split -l 112 ../bigfile.csv
我想将大文件分成小文件,每个文件有一个入口(112行),并将每个文件的名称设置为" Id"的值,我的意思是例如AP64531346-2016055553824 .txt和AP24531346-20160676553824分别。
我尝试使用GNU Split但我无法将每个文件的名称设置为Id plus .txt。
"Error: Invalid domain for site key"
有什么建议吗?
答案 0 :(得分:2)
分两步:首先使用
生成一般命名的文件split -l 112 ../bigfile.csv
现在你有了xaa
,xab
等文件。我认为这些是目录中的唯一文件。现在你可以遍历它们,提取Id并重命名它们:
for file in *; do
newname="$(grep -m 1 -Po '(?<="Id": ")[^"]+' "$file")"
mv "$file" "$newname.txt"
done
grep -o
仅提取匹配项,并使用零宽度&#34; look-behind&#34;得到Id行。仅在使用Perl正则表达式引擎(-P
)时才能查看。 -m 1
在第一场比赛后停止,因此当您知道第一场比赛足够好时,您就不会浏览整个文件。
当每个块没有112行时,这当然会严重破坏 - proper solution会解析文件。
答案 1 :(得分:2)
听起来您想将每个JSON文档放在自己的文件中。您可以使用JSON :: XS的增量解析器来执行此操作。
use JSON::XS qw( );
my $json = JSON::XS->utf8->new();
local $/ = \(1024*1024)
while (<>) {
for my $obj ($json->incr_parse($_)) {
my $id = $obj->{Id};
open(my $fh, '>', $id . ".txt")
or die $!;
print($fh $json->encode($obj));
}
}
答案 2 :(得分:1)
该任务的一般方法(即,不对输入文件中的JSON实体流做任何假设的方法,除了它们是有效的JSON实体之外)由以下&#34; one-liner& #34;:
jq -cr '"\(.Id)\t\(.)"' | awk -F\\t '{print $2 > "/tmp/"$1".json"}'
这使用&#34; JSON查询&#34; (jq)命令行处理器,可在许多平台上使用。
如果您希望每个新文件都是漂亮的,那么您可以在第二步中使用jq,例如:
ls *.json | while read f ; do jq . "$f" > "$f.tmp" && mv "$f.tmp" "$f" ; done
答案 3 :(得分:1)
JSON结构与perl数据结构高度兼容,因此可以使用eval快速分离不同文件中的记录。考虑到你json没有在值
中持有“:”local $/ = undef;
open FILE, "Testjson.txt" or die "Couldn't open file: $!";
my $string = <BiGFILE>;
close FILE;
$string =~ s/:/,/g;
$jsonStr = eval $string;
foreach my $record (@{$jsonStr}) {
print $record->{'Id'} . "\n";
}