【问题标题】:Processing JSON of arrays in array with jq用 jq 处理数组中数组的 JSON
【发布时间】:2015-05-21 16:30:19
【问题描述】:

环境:JQ 1.5,Windows 64 位。

我有以下 JSON:

{
  "unique": 1924,
  "coordinates": [
    {
      "time": "2015-01-25T00:00:01.683",
      "xyz": [
        {
          "z": 4,
          "y": 2,
          "x": 1,
          "id": 99
        },
        {
          "z": 9,
          "y": 9,
          "x": 8,
          "id": 100
        },
        {
          "z": 9,
          "y": 6,
          "x": 10,
          "id": 101
        }
      ]
    },
    {
      "time": "2015-01-25T00:00:02.790",
      "xyz": [
        {
          "z": 0,
          "y": 3,
          "x": 7,
          "id": 99
        },
        {
          "z": 4,
          "y": 6,
          "x": 2,
          "id": 100
        },
        {
          "z": 2,
          "y": 9,
          "x": 51,
          "id": 101
        }
      ]
    }
  ]
}

并想用 jq 将其转换成这种 CSV 格式:

unique,time,id,x,y,z
1924,"2015-01-25T00:00:01.683",99,1,2,4
1924,"2015-01-25T00:00:01.683",100,8,9,9

(等等)

我尝试了一些方法,例如:

jq -r '{unique: .unique, coordinates: .coordinates[].xyz[] | [.id, .x, .y, .z], time: .coordinates.[].time} | flatten | @csv' 

这给了我我想要的 JSON,但对每个 id、x、y 和 z 乘以(即每个唯一的行出现四次 - id、x、y、z 各出现一次)。

给数组赋值,比如

jq -r '{unique: .unique, coordinates: .coordinates[0].xyz[] | [.id, .x, .y, .z], time: .coordinates.[0].time} | flatten | @csv' 

给了我coordinates 数组的第一个索引,但我自然想要所有这些索引。

【问题讨论】:

  • 什么语言? Javascript?
  • 嗯。需要一个最近的版本,那里;我还在1.4。但是,这就是闪亮特征的方式......

标签: json jq


【解决方案1】:

第一步是将结果扁平化为行。

[{ unique } + (.coordinates[] | { time } + .xyz[])]

这将在每行产生一个对象数组:

[
  {
    "unique": 1924,
    "time": "2015-01-25T00:00:01.683",
    "id": 99,
    "x": 1,
    "y": 2,
    "z": 4
  },
  {
    "unique": 1924,
    "time": "2015-01-25T00:00:01.683",
    "id": 100,
    "x": 8,
    "y": 9,
    "z": 9
  },
  {
    "unique": 1924,
    "time": "2015-01-25T00:00:01.683",
    "id": 101,
    "x": 10,
    "y": 6,
    "z": 9
  },
  {
    "unique": 1924,
    "time": "2015-01-25T00:00:02.790",
    "id": 99,
    "x": 7,
    "y": 3,
    "z": 0
  },
  ...
]

然后只需将其转换为 csv 行即可。

["unique","time","id","x","y","z"] as $fields | $fields, (.[] | [.[$fields[]]]) | @csv

【讨论】:

  • 谢谢!我一直在对以前的命令使用 flatten / @csv 范例 - 你说转换为 CSV 的方法是更快/更有效吗?
  • 我不认为flatten 真的可以在这里工作。它旨在展平数组,而不是对象。而且您不想使用它,因为展平对象会产生值。您将丢失关联的密钥,并且无法保证订购。您需要转换为其他中间形式才能更好地利用它。我在这里采用的方法更直接,因此我希望它比尝试使用 flatten 更快。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多