jqを使用してJSONデータを解析してcsvに変換する

jqを使用してJSONデータを解析してcsvに変換する

私はapi jsonデータをダウンロードし、csvファイル形式で最終結果に変換しています。

サンプルデータ形式は次のとおりです。

{
    "content": [{
            "Title": "abc",
            "brand": "xyz",
            "information": {
                "c1": "101",
                "c2": "11111",
                "c3": "a,b,c,d,e:abc."
            }
        },
        {
            "Title": "RX100",
            "brand": "Yamaha",
            "information": {
                "c1": "102",
                "c2": "22222",
                "c3": "a."
            }
        },
        {
            "Title": "victor",
            "brand": "TVS",
            "information": {
                "c1": "103",
                "c2": "33333",
                "c3": "a,b,c"
            }
        },
        {
            "Title": "R15",
            "brand": "Yamaha",
            "information": {
                "c1": "104",
                "c2": "44444",
                "c3": "a,b"
            }
        }
    ]
}

ヘッダーの数に応じて、複数のcsvに正常にダウンロードして変換しました。複数のcsvファイルに変換した後、データは次のようになります。

Headers-> c1,c2,c3
csv1-->   101,11111,a,b,c,d,e:abc.
csv2-->   102,22222,a.
csv3-->   103,33333,a,b,c.
csv4-->   104,44444,a,b.

しかし、上記のデータを次の形式にしたいと思います。

Headers-> c1,c2,c3,c4,c5,c6,c7
csv1-->   101,11111,a,b,c,d,e:abc.
csv2-->   102,22222,a.
csv3-->   103,33333,a,b,c.
csv4-->   104,44444,a,b.

json.jsonを使用して、私のjsonファイルの「、」に基づいてc3を異なる数の列に分割できますか? c3列は、存在する要素の数によって分割され、c3データの最大値になります。

ベストアンサー1

この正確なデータのために

jq -r '.content[].information | [.c1, .c2, .c3] | join(",")' < sample.json

動作します。リンクされたCSVファイルの効果を複製するには、3つの列の間にカンマを挿入するだけです。より複雑な実際のデータ、特に数値の場合は、次の方が良いです。

jq -r '.content[].information | [.c1, .c2, (.c3|split(",")|.[])] | @csv' < sample.json

それはすべてかなり標準的.c3|split(",")|.[]です。

  1. 3列の値を抽出します。
  2. 値をカンマ配列に分割する
  3. 配列の平面化

@csv次に、配列をCSV形式に変換します。これにより、サンプルファイルに対して次の出力が生成されます。

"101","11111","a","b","c","d","e:abc."
"102","22222","a."
"103","33333","a","b","c"
"104","44444","a","b"

引用符が必要ない場合は、最も安定した方法は@tsvタブを使用して置き換えることです。

jq -r '.content[].information|[.c1, .c2, .c3|split(",")|.[]] | @tsv|gsub("\t"; ",")' < sample.json

すべての値が文字列の場合でも、join(",")それを再利用できます。


テキストヘッダー行も生成するには、次のようにc1,...c7します。

jq -r '[.content[].information|[.c1, .c2, (.c3|split(",")|.[])]] | (([range([.[] | length] | max)|"c" + (.+1|tostring)]|join(",")), (.[] | join(",")))' < sample.json

3つの部分で構成されています。最初の部分は以前と同様に列配列を作成し、残りの2つの部分はそれを入力として使用します。

  1. ([range([.[] | length] | max)|"c" + (.+1|tostring)]|join(","))ヘッダー行の作成:行長の配列を作成し、0..maximumの範囲を作成し、それをマッピングして "c1".."c7"配列を作成し、すべてコンマで連結して行の最大長を見つけます。 。
  2. (.[] | join(","))前の後半戦と同様に@csv適用されます。

おすすめ記事