问题描述
我正在尝试转换csv,其中标头是键,列中的值是列表。
例如,我有以下csv
mpg cyl disp hp drat wt qsec vs am gear carb
Mazda RX4 21 6 160 110 3.9 2.62 16.46 0 1 4 4
Mazda RX4 Wag 21 6 160 110 3.9 2.875 17.02 0 1 4 4
Datsun 710 22.8 4 108 93 3.85 2.32 18.61 1 1 4 1
我想要以下格式。
{
"field1" : [Mazda RX4,Mazda RX4 Wag,Datsun 710],"mpg" : [21,21,22.8],"cyl" : [6,6,6],"disp" : [160,160,108],...
}
请注意,未引用数值。我假设所有列都具有相同的类型。
我正在使用以下jq
命令。
curl https://raw.githubusercontent.com/vincentarelbundock/Rdatasets/master/csv/datasets/mtcars.csv cars.csv | head -n4 | csvtojson | jq '.'
[
{
"field1": "Mazda RX4","mpg": "21","cyl": "6","disp": "160","hp": "110","drat": "3.9","wt": "2.62","qsec": "16.46","vs": "0","am": "1","gear": "4","carb": "4"
},{
"field1": "Mazda RX4 Wag","wt": "2.875","qsec": "17.02",{
"field1": "Datsun 710","mpg": "22.8","cyl": "4","disp": "108","hp": "93","drat": "3.85","wt": "2.32","qsec": "18.61","vs": "1","carb": "1"
}
]
解决方法
这是一个基于map
和reduce
的简洁,高效且概念上简单的解决方案:
. as $in
| reduce (.[0] | keys_unsorted[]) as $k ( {}; .[$k] = ($in|map(.[$k])))
将所有数值字符串转换为数字
. as $in
| reduce (.[0] | keys_unsorted[]) as $k ( {};
.[$k] = ($in|map(.[$k] | (tonumber? // .))))