[英]Convert CSV to Nested JSON using / header delimiter
我的 CSV 标头看起来像
来自/电子邮件 | 到/0/电子邮件 | 个性化/0/电子邮件/ | 个性化/0/data/first_name | 个性化/0/数据/公司名称 | 个性化/0/data/job_title | 模板编号 |
---|
Output 应该是:
[
{
"from": {
"email": "me@x.com",
"name": "Me"
},
"to": [
{
"email": "mike@x.com"
}
],
"personalization": [
{
"email": "mike@x.com",
"data": {
"first_name": "Mike",
"company_name": "X.com",
"job_title": "Chef"
}
}
],
"template_id": "123456"
},
我试过了
csvjson input.csv output.csv
csvtojson input.csv output.csv
csv2json input.csv output.csv
python3 app.py
import csv
import json
def csv_to_json(csvFilePath, jsonFilePath):
jsonArray = []
#read csv file
with open(csvFilePath, encoding='utf-8') as csvf:
#load csv file data using csv library's dictionary reader
csvReader = csv.DictReader(csvf)
#convert each csv row into python dict
for row in csvReader:
#add this python dict to json array
jsonArray.append(row)
#convert python jsonArray to JSON String and write to file
with open(jsonFilePath, 'w', encoding='utf-8') as jsonf:
jsonString = json.dumps(jsonArray, indent=4)
jsonf.write(jsonString)
csvFilePath = r'outputt1.csv'
jsonFilePath = r'outputt1.json'
csv_to_json(csvFilePath, jsonFilePath)
node app.js
const CSVToJSON = require('csvtojson');
// convert users.csv file to JSON array
CSVToJSON().fromFile('outputt1.csv')
.then(from => {
// from is a JSON array
// log the JSON array
console.log(from);
}).catch(err => {
// log error if any
console.log(err);
});
所有 output 单行 JSON 的一些变体,没有嵌套。
唯一可行的是将其上传到https://www.convertcsv.com/csv-to-json.htm并手动转换每个文件,但这显然不是解决方案。
我看到一个帖子推荐 Choetl.Json 用于这个确切的目的,但无法在 mac 上安装它
您的问题应该分为两部分:解析 CSV 数据以转换为 JSON,并按照类似路径的说明构建 JSON 结构。
对于第一部分,有必要澄清 CSV 输入的格式,因为 CSV 没有通用标准,只是RFC 4180 提案中的基本描述以及针对特定用例或数据类型量身定制的大量采用。 为了简单起见,我们假设记录由换行符分隔,字段由逗号分隔,并且没有字段分隔符,因为数据本身从不包含任何这些分隔符。 让我们进一步假设恰好有一个(第一个)记录表示标题,并且所有记录都具有完全相同数量的字段。 您可能希望将这些假设调整为您的实际 CSV 数据。
然后,要读入 CSV 数据,请使用-R
选项将输入视为以换行符分隔的原始文本行,并使用/
运算符拆分行:
cat input.csv
from/email,to/0/email,personalization/0/email,personalization/0/data/first_name,personalization/0/data/company_name,personalization/0/data/job_title,template_id
me@x.com,mike@x.com,mike@x.com,Mike,X.com,Chef,123456
jq -R '. / ","' input.csv
[
"from/email",
"to/0/email",
"personalization/0/email",
"personalization/0/data/first_name",
"personalization/0/data/company_name",
"personalization/0/data/job_title",
"template_id"
]
[
"me@x.com",
"mike@x.com",
"mike@x.com",
"Mike",
"X.com",
"Chef",
"123456"
]
As for the second part, you can make use of functions like setpath
which interpret arrays as object structure paths, then split your header names into an array using /
again, and build up your JSON objects by iterating through the fields using a reduce
statement. 我还假设 header 路径中的数字始终表示数组 inices(并且从不具有看起来像数字的字符串名称的字段名称)。 我使用tonumber
将它们转换,并使用transpose
将 header 字段与数据字段对齐:
… | jq -s '
(.[0] | map(. / "/" | map(tonumber? // .))) as $headers
| .[1:] | map(
reduce ([$headers, .] | transpose[]) as [$path, $value] (
{}; setpath($path; $value)
)
)
'
[
{
"from": {
"email": "me@x.com"
},
"to": [
{
"email": "mike@x.com"
}
],
"personalization": [
{
"email": "mike@x.com",
"data": {
"first_name": "Mike",
"company_name": "X.com",
"job_title": "Chef"
}
}
],
"template_id": "123456"
}
]
你可能想试试米勒。 它以static 二进制文件的形式提供,因此您只需将mlr
可执行文件放在某处(最好在您的 PATH 中)即可完成安装。
mlr --icsv --ojson --jflatsep / cat file.csv
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.