2016-07-26 2 views
2

Я работаю на Mac и имею очень большой файл .json с более чем 100k объектами.Сплит .json файл в несколько файлов на Mac

Я хотел бы разбить файл на множество файлов (желательно 50-100).

SOURCE FILE

Исходный файл .json представляет собой многомерный массив и выглядит как это:

[{ 
    "id": 1, 
    "item_a": "this1", 
    "item_b": "that1" 
}, { 
    "id": 2, 
    "item_a": "this2", 
    "item_b": "that2" 
}, { 
    "id": 3, 
    "item_a": "this3", 
    "item_b": "that3" 
}, { 
    "id": 4, 
    "item_a": "this4", 
    "item_b": "that4" 
}, { 
    "id": 5, 
    "item_a": "this5", 
    "item_b": "that5" 
}] 

ХОЧЕТ ВЫХОДА

Если это были разделены на три файла Я хотел бы, чтобы результат выглядел так:

Файл 1:

[{ 
    "id": 1, 
    "item_a": "this1", 
    "item_b": "that1" 
}, { 
    "id": 2, 
    "item_a": "this2", 
    "item_b": "that2" 
}] 

Файл 2:

[{ 
    "id": 3, 
    "item_a": "this3", 
    "item_b": "that3" 
}, { 
    "id": 4, 
    "item_a": "this4", 
    "item_b": "that4" 
}] 

Файл 3:

[{ 
    "id": 5, 
    "item_a": "this5", 
    "item_b": "that5" 
}] 

Любые идеи, было бы весьма признателен. Спасибо!

ответ

3

Perl на помощь:

#!/usr/bin/perl 
use warnings; 
use strict; 

use JSON; 

my $file_count = 5; # You probably want 50 - 100 here. 

my $json_text = do { 
    local $/; 
    open my $IN, '<', '1.json' or die $!; 
    <$IN> 
}; 
my $arr = decode_json($json_text); 
my $size = @$arr/$file_count; 
my $rest = @$arr % $file_count; 

my $i = 1; 
while (@$arr) { 
    open my $OUT, '>', "file$i.json" or die $!; 
    my @chunk = splice @$arr, 0, $size; 
    ++$size if $i++ >= $file_count - $rest; 
    print {$OUT} encode_json(\@chunk); 
    close $OUT or die $!; 
} 
3

@ ответ choroba является очень эффективным и гибким. У меня есть решение bash с jq.

#!/bin/bash 
i=0 
file=0 
for f in `cat data.json | jq -c -M '.[]'`; 
do 

    if [ $i -eq 2 ]; then 

     ret=`jq --slurp "." /tmp/0.json /tmp/1.json > File$file.json`; 
     ret=`rm /tmp/0.json /tmp/1.json`; #cleanup 

     ((file = file + 1)); 
    i=0 
    fi 
    ret=`echo $f > /tmp/$i.json`; 
    ((i = i + 1)); 
done 
if [ -f /tmp/0.json ]; then 
    ret=`jq --slurp '.' /tmp/0.json > File$file.json`; 
    ret=`rm /tmp/0.json`; #cleanup 
fi 
1
$ cat tst.awk 
/{/ && (++numOpens % 2) { 
    if (++numOuts > 1) { 
     print out, "}]" 
     close(out) 
    } 
    out = "out" numOuts 
    $0 = "[{" 
} 
{ 
    # print > out 
    print out, $0 
} 

.

$ awk -f tst.awk file 
out1 [{ 
out1  "id": 1, 
out1  "item_a": "this1", 
out1  "item_b": "that1" 
out1 }, { 
out1  "id": 2, 
out1  "item_a": "this2", 
out1  "item_b": "that2" 
out1 }] 
out2 [{ 
out2  "id": 3, 
out2  "item_a": "this3", 
out2  "item_b": "that3" 
out2 }, { 
out2  "id": 4, 
out2  "item_a": "this4", 
out2  "item_b": "that4" 
out2 }] 
out3 [{ 
out3  "id": 5, 
out3  "item_a": "this5", 
out3  "item_b": "that5" 
out3 }] 

Просто удалите print out, $0 и раскомментируйте # print > out после того как вы испытаны и счастливы с ним.

+0

Спасибо, ред. Я думаю, что это очень близко. Он корректно печатает на моем терминале во время тестирования, но когда я удаляю 'print out, $ 0' и раскомментирую' # print $ 0> out', конец out1 и out2 печатается в терминале, но не включается в файлы. '}]' Останавливается и просто печатается в терминале. Любые идеи о том, как их решить? Спасибо! – Brandon

+0

Вы, должно быть, скопировали/вклеили неправильно или раскомментировали неправильно. Сценарий, который я написал **, не будет делать то, что вы описываете. Если вы отредактируете свой вопрос, чтобы показать скрипт, который вы используете, мы сможем его отладить. –

+0

Это не удастся, если какой-либо ключ или значение содержит символ '{'. –

Смежные вопросы