jq配列内のオブジェクトの特定の値のみを使用してリストを選択して配列を変換します。

jq配列内のオブジェクトの特定の値のみを使用してリストを選択して配列を変換します。

私は次のオブジェクトを持っています

{
  "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",
  ],
}

いくつか試してみましたが、まだ何をすべきかわかりません。

答え1

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

これでfields配列が更新されます。まず、各要素に対して(使用)map()キーkeyの値を使用してキーを作成しますname。次に、要素からtypeキーを削除しますlinkedId。これで、配列の各要素にnameaとキーが残りますkey。これは正確に値をキー値に関連付ける必要がある場所です。valuefieldsfrom_entrieskeyvalue

質問に提供されたデータをテストすると(末尾のカンマを削除する)、次の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元の値が同じ2つの要素が結果で互いに上書きされないことです。


概念的には、削除不要になったデータ。下の変形タブレット私たちが望むデータ。

これにより、上記の最終結果が生成されます。

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

fieldsリスト内の項目をマージして、最初の結果(単一オブジェクト)を取得できます。

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

関連情報