jqを使用してオブジェクトリストからフィールドとサブフィールドを抽出し、サブフィールドのペアをグループ化してcsvに保存します。

jqを使用してオブジェクトリストからフィールドとサブフィールドを抽出し、サブフィールドのペアをグループ化してcsvに保存します。

このデータを使用すると、次のようになります。

[
  {
    "c": "A",
    "e": "B",
    "score": 0.99,
    "v": [
      {
        "context": "asdf",
        "score": 0.98,
        "url": "..."
      },
      {
        "context": "bcdfd",
        "score": 0.97,
        "url": "..."
      }
    ]
  },
  { 
    ...
  }
]

(外部リスト参照)

次を抽出しようとしています。

A, B, 0.99, asdf, 0.98, bcdfd, 0.97

だから私ができる最善は

jq -r '.[] | [.c, .e, .score, .v[].context, .v[].score ] | @csv' 

これは

A, B, 0.99, asdf, bcdfd, 0.998, 0.97

私はそれぞれの価値観を知って編むのではなく、ただ吐き出す.v[].context.v[score]

私が逃している魔法は何ですか?

答え1

.context,.score私が考える各要素に対してフィルタを実行したいと思いますv

$ jq -r '.[] | [.c, .e, .score, (.v[] | .context,.score)] | @csv' file.json
"A","B",0.99,"asdf",0.98,"bcdfd",0.97

mapこれは、結果を配列にまとめずに組み込み関数を使用するのと同じです。

答え2

以下は、最上位の配列要素ごとにJSONでエンコードされたCSVレコードを生成し、それを抽出してデコードします。各最上位要素について、サブ配列値は配列を「平坦化」することによって結合される。

jq -r 'map([ .c,.e,.score, (.v|map([.context, .score])) ] | flatten | @csv)[]' file

以下のテスト文書が提供されます。

[
   {
      "c": "A",
      "e": "B",
      "score": 0.99,
      "v": [
         { "context": "asdf", "score": 0.98, "url": "..." },
         { "context": "bcdfd", "score": 0.97, "url": "..." }
      ]
   },
   {
      "c": "A",
      "e": "B",
      "score": 0.99,
      "v": [
         { "context": "asdf", "score": 0.98, "url": "..." },
         { "context": "asdf", "score": 0.98, "url": "..." },
         { "context": "bcdfd", "score": 0.97, "url": "..." }
      ]
   },
   {
      "c": "A",
      "e": "B",
      "score": 0.99,
      "v": [
         { "context": "asdf", "score": 0.98, "url": "..." },
         { "context": "asdf", "score": 0.98, "url": "..." },
         { "context": "asdf", "score": 0.98, "url": "..." },
         { "context": "bcdfd", "score": 0.97, "url": "..." }
      ]
   }
]

...私たちは得ました

"A","B",0.99,"asdf",0.98,"bcdfd",0.97
"A","B",0.99,"asdf",0.98,"asdf",0.98,"bcdfd",0.97
"A","B",0.99,"asdf",0.98,"asdf",0.98,"asdf",0.98,"bcdfd",0.97

@csv演算子を一度使用して一連の配列を取得するように(@csv単一の配列で再利用せずに)作業順序を変更することもできます。

jq -r 'map([ .c,.e,.score, (.v|map([.context, .score])) ] | flatten)[]|@csv' file

関連情報