Преобразование больших CSV в несколько массивов фиксированных записей JSON (например, 100 записей массивов json) с помощью Shell - PullRequest
0 голосов
/ 07 ноября 2019

Как преобразовать большой CSV в массив JSON с фиксированным набором записей (массив JSON из 100 записей) с помощью сценария SHELL или командной строки?

Например. входного CSV-файла:

identifier,type,locale
91617676848,MSISDN,es_ES
91652560975,MSISDN,es_ES
91636563675,MSISDN,es_ES

Ожидаемый результат:

1.json  (json array having 100 array records)
  [
  {
    "identifier": "91617676848",
    "type": "MSISDN",
    "locale": "es_ES"
  },
  .
  .
  .
  .
  {
    "identifier": "91652560975",
    "type": "MSISDN",
    "locale": "es_ES"
  }
  ]


  2.json (json array having 100 array records)
  [
  {
    "identifier": "91636563675",
    "type": "MSISDN",
    "locale": "es_ES"
  },
  .
  .
  .
  .

  {
    "identifier": "91636563999",
    "type": "MSISDN",
    "locale": "es_ES"
  }
  ]

Ответы [ 3 ]

0 голосов
/ 08 ноября 2019

Пожалуйста, попробуйте решение awk:

awk -v bs=10 '
    NR == 1 {
        cols = split($0, header, ",")
        next
    }
    {
        if ((NR - 1) % bs == 1) {
            file = sprintf("%d.json", ++n)
            print "[\n  {" > file
        } else {
            print ",\n  {" >> file
        }
        split($0, a, ",")
        for (i = 1; i <= cols; i++) {
            printf("    \"%s\": \"%s\"", header[i], a[i]) >> file
            print (i < cols) ? "," : "" >> file
        }
        printf "%s", "  }" >> file
    }
    (NR - 1) % bs == 0 {
        print "\n]" >> file
        close(file)
    }
    END {
        if ((NR - 1) % bs != 0) print "\n]" >> file
    }
' input.csv

Переменная bs содержит количество массивов на файл.
Она обрабатывает входной файл построчно и имеет так многоусловные ветви для создания правильных файлов json. Вздох.

0 голосов
/ 08 ноября 2019

Используя реализацию bash, задача может быть выполнена путем многократного отрезания диапазона строк от файла (2-101, 102-201, ...) до конца файла. Приведенный ниже код использует sed для извлечения строки и csvjson для форматирования каждого блока в JSON.

Вы можете заменить любой из ваших любимых инструментов (существует несколько альтернатив csv-json).

Код немного более подробный, чем нужно.

#! /bin/sh
csv=$1
lines=$(wc -l < $csv)
blocks=$((1+(lines-1)/100))
for (( i=1 ; i <= blocks ; i++ )) ; do
    sed -ne "1p;$((i*100-98)),$((i*100+1))p" $csv | csvjson -i2 > $i.json
done

При разумном размере файла повторная обработка входного файла не потребует больших затрат

0 голосов
/ 07 ноября 2019

Я создал простой php-скрипт (я назвал его converter.php).

Вы можете вызвать как есть: php converter.php test.csv, где test.csv содержит и данные по умолчанию csv с первой строкой в ​​качестве заголовка.

<?php
    // open the file passed as parameter
    // Ex: php converter.php test.csv
    // Where test.csv contains the data passed on question
    if (($handle = fopen($argv[1], 'r')) !== false) {
            $count = 0;
            $lines = [];
            while (($data = fgetcsv($handle, 0, ',', '\'')) !== false) {
                    if ($count == 0) {
                        $headers = $data;
                    } else {
                        $lines[] = array_combine($headers, $data);
                    }
                    $count++;
            }
            // Here, separate in array of arrays with 100 elements on each
            // On test i used 2 on second parameter of array_chunk to test with your toy data
            $groups = array_chunk($lines, 100);
            foreach ($groups as $key => $group) {
                    file_put_contents('json_data-'.$key.'.json', json_encode($group));
            }
    }

Я работаю локально и разделил файлы на два элемента, чтобы проверить его, в результате чего два файла были сохранены локально с именем json_data-<key>.json

И результаты здесь:

  • json_data-0.json:

    [{"identifier": "91617676848", "type": "MSISDN", "locale": "es_ES"}, {"identifier":" 91652560975 "," type ":" MSISDN "," locale ":" es_ES "}]

  • json_data-1.json:

    [{"идентификатор ":" 91636563675 "," тип ":" MSISDN "," языковой стандарт ":" es_ES "}]

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...