0

如何通过 SHELL 脚本或命令行将大型 CSV 转换为固定记录集的 JSON 数组(100 条记录的 JSON 数组)?

例如。输入 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"
  }
  ]
4

3 回答 3

0

使用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

假设文件大小合理,重新处理输入文件不会产生大量开销

于 2019-11-08T03:55:05.463 回答
0

请您尝试一个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 文件。叹。

于 2019-11-08T03:54:38.037 回答
0

我创建了一个简单的 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”}]

于 2019-11-07T20:45:42.663 回答