Json

jq 通過僅使用數組中對象的某些值選擇列表來轉換數組

  • September 17, 2022

我有以下對象

{
 "name": "Papanito",
 "fields": [
   {
     "name": "Name1",
     "value": "Value1",
     "type": 0,
     "linkedId": null
   },
   {
     "name": "Name2",
     "value": "Value2",
     "type": 0,
     "linkedId": null
   },
   {
     "name": "Name3",
     "value": "Value3",
     "type": 0,
     "linkedId": null
   },
   {
     "name": "Name4",
     "value": "Value3",
     "type": 0,
     "linkedId": null
   }
 ],
}

我想在這個轉換

{
 "name": "Papanito",
 "fields": [
   "Name1": "Value1",
   "Name2": "Value2",
   "Name3": "Value3",
   "Name4": "Value4",
 ],
}

我嘗試了幾件事,但我還沒有弄清楚如何做到這一點。

jq '.fields |= ( map(.key = .name | del(.type,.linkedId,.name)) | from_entries )' file

這將更新fields數組。首先,對於每個元素(使用map()),使用key鍵中的值創建一個name鍵。然後從元素中刪除typelinkedId和鍵。name我們現在在數組的每個元素中都留下了一個key和一個鍵,這正是需要將值作為鍵與值相關聯的地方。value``fields``from_entries``key``value

對問題中給出的數據進行測試(刪除了尾隨逗號),這會生成以下 JSON:

{
 "name": "Papanito",
 "fields": {
   "Name1": "Value1",
   "Name2": "Value2",
   "Name3": "Value3",
   "Name4": "Value3"
 }
}

請注意,您的預期輸出是無效的 JSON,因為數組不能有鍵。因此,fields上面輸出中的值是一個對象,而不是一個數組。

您是否想保留fields為數組,您可以重新排列操作:

jq '.fields |= map([.key = .name | del(.type,.linkedId,.name)] | from_entries)' file

對於給定的數據(如上所述更正),這將生成與以下文件等效的內容:

{
  "name": "Papanito",
  "fields": [
     { "Name1": "Value1" },
     { "Name2": "Value2" },
     { "Name3": "Value3" },
     { "Name4": "Value3" }
  ]
}

這樣做的好處是具有相同原始name值的兩個元素不會在結果中相互覆蓋。


從概念上講,上面刪除了我們不再需要的數據。以下變體提取了我們想要的數據。

這會從上面生成最後一個結果:

jq '.fields |= map({ (.name): .value })' file

我們可以通過合併列表中的條目來獲得第一個結果(fields作為單個對象):

jq '.fields |= (map({ (.name): .value }) | add)' file

引用自:https://unix.stackexchange.com/questions/717623