如何使用 jq 将 object 键转换为数组

How to convert object keys to arrays with jq

我正在尝试转换一个 csv,其中 headers 是键,列中的值是一个列表。

例如我有以下 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",
    "mpg": "21",
    "cyl": "6",
    "disp": "160",
    "hp": "110",
    "drat": "3.9",
    "wt": "2.875",
    "qsec": "17.02",
    "vs": "0",
    "am": "1",
    "gear": "4",
    "carb": "4"
  },
  {
    "field1": "Datsun 710",
    "mpg": "22.8",
    "cyl": "4",
    "disp": "108",
    "hp": "93",
    "drat": "3.85",
    "wt": "2.32",
    "qsec": "18.61",
    "vs": "1",
    "am": "1",
    "gear": "4",
    "carb": "1"
  }
]

完整的工作解决方案

cat <csv_data> | csvtojson | jq '. as $in | reduce (.[0] | keys_unsorted[]) as $k ( {}; .[$k] = ($in|map(.[$k])))'

jq play - 将所有数字转换为字符串

https://jqplay.org/s/HKjHLVp9KZ

这是一个基于 mapreduce 的简洁、高效且概念简单的解决方案:

. 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? // .))))