簡體   English   中英

使用 jq 展平 JSON 文檔

[英]Flatten a JSON document using jq

我正在考慮以下 JSON 對象數組:

[
  {
    "index": "index1",
    "type": "type1",
    "id": "id1",
    "fields": {
      "deviceOs": [
        "Android"
      ],
      "deviceID": [
        "deviceID1"
      ],
      "type": [
        "type"
      ],
      "country": [
        "DE"
      ]
    }
  },
  {
    "index": "index2",
    "type": "type2",
    "id": "id2",
    "fields": {
      "deviceOs": [
        "Android"
      ],
      "deviceID": [
        "deviceID2"
      ],
      "type": [
        "type"
      ],
      "country": [
        "US"
      ]
    }
  }
]

我想將其展平以獲得:

[
  {
    "index": "index1",
    "type": "type",
    "id": "id1",
    "deviceOs": "Android",
    "deviceID": "deviceID1",
    "country": "DE"
  },
  {
    "index": "index2",
    "type": "type",
    "id": "id2",
    "deviceOs": "Android",
    "deviceID": "deviceID2",
    "country": "US"
  }
]

我正在嘗試與jq合作,但我無法展平"fields" 我應該怎么做? 目前我對命令行工具很感興趣,但我也願意接受其他建議。

這個是一個棘手的工藝。

map
(
    with_entries(select(.key != "fields"))
    +
    (.fields | with_entries(.value = .value[0]))
)

讓我們分解並解釋它的各個部分

  1. 對於陣列中的每個項目......

     map(...) 
  2. 創建一個新對象,其中包含除fields屬性之外的所有值。

     with_entries(select(.key != "fields")) 
  3. 結合......

     + 
  4. 每個fields每個值投影到每個數組的第一項

     (.fields | with_entries(.value = .value[0])) 

您可以使用此過濾器:

[.[] | {index: .index, type: .type, id: .id, deviceOs: .fields.deviceOs[],deviceID: .fields.deviceID[],country: .fields.country[]}]

你可以在這里測試https://jqplay.org

下面是一些變體,首先將.fields合並到包含對象中,然后展開數組元素。 首先我們照顧.fields

  .[]
| . + .fields
| del(.fields)

這讓我們看起來像是一樣的物體

{
  "index": "index1",
  "type": [
    "type"
  ],
  "id": "id1",
  "deviceOs": [
    "Android"
  ],
  "deviceID": [
    "deviceID1"
  ],
  "country": [
    "DE"
  ]
}

然后我們可以多種方式壓扁鍵。 一種方法是使用with_entries

| with_entries( .value = if .value|type == "array" then .value[0] else .value end )

另一種方法是使用reducesetpath

| . as $v
| reduce keys[] as $k (
    {};
    setpath([$k]; if $v[$k]|type != "array" then $v[$k] else $v[$k][0] end)
  )

有一個名為gron的工具,你可以管道json,以獲得這樣的東西。

$ gron document.json
json = [];
json[0] = {};
json[0].fields = {};
json[0].fields.country = [];
json[0].fields.country[0] = "DE";
json[0].fields.deviceID = [];
json[0].fields.deviceID[0] = "deviceID1";
json[0].fields.deviceOs = [];
json[0].fields.deviceOs[0] = "Android";
json[0].fields.type = [];
json[0].fields.type[0] = "type";
json[0].id = "id1";
json[0].index = "index1";
json[0].type = "type1";
json[1] = {};
json[1].fields = {};
json[1].fields.country = [];
json[1].fields.country[0] = "US";
json[1].fields.deviceID = [];
json[1].fields.deviceID[0] = "deviceID2";
json[1].fields.deviceOs = [];
json[1].fields.deviceOs[0] = "Android";
json[1].fields.type = [];
json[1].fields.type[0] = "type";
json[1].id = "id2";
json[1].index = "index2";
json[1].type = "type2";

類似於@jq170727 anwser:

jq 'map(. + (.fields | with_entries(.value |= .[])) | del(.fields))'

(假設.fields中沒有字段本身稱為.fields )。

|with_entries(.value|=.[])部分是將 .fields 中的值.fields展平——注意只保留第一項。 .value|=join(", ")可用於將多個字符串值合並為一個。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM