日: 2023年6月3日

  • jqコマンドでJSONから指定した項目を取得・変換する

    jqコマンドでJSONから指定した項目を取得・変換する

    JSONはウェブのデータ交換形式として広く使われていますが、大量のデータを扱うときはデータをフィルタリングしたり整形したりすることが必要になることがあります。今回は、jqコマンドを使ってJSONから特定の項目を取り出し、新しい形式に整形する方法、特定の条件にマッチするレコードのみを選択する方法、そしてmap関数の使い方を紹介します。

    JSONデータの例

    以下に、我々が今回扱うサンプルのJSONデータを示します:

    {
    "records": [
    {
    "id": 1234,
    "user": {
    "id": 5678,
    "account": "user1@example.com",
    "status": 0,
    "attributes": []
    },
    "attributes": [
    {
    "values": [
    {
    "value": "2023-01-01T00:00:00"
    }
    ],
    "id": 2,
    "name": "Date"
    },
    {
    "values": [
    {
    "value": "AB01"
    }
    ],
    "id": 1,
    "name": "Code"
    }
    ]
    }
    ],
    "meta": {
    "totalCount": 999,
    "page": 1,
    "countPerPage": 1,
    "maxPage": 999
    }
    }

    このデータには複数のレコードが含まれ、各レコードにはuser情報とattributes情報があります。

    jqコマンドで特定の項目を取得

    今回の目的は、各レコードから特定の項目を取得し、それを新しい形式に整形することです。これを達成するために、jqコマンドを使用します。

    以下に、新しい形式にデータを整形するためのjqコマンドを示します:

    jq '[.records[] | {EmployeeNumber: .user.id, Email: .user.account, GradeDate: .attributes[0].values[0].value, Grade: .attributes[1].values[0].value}]' input.json

    このコマンドは以下の操作を行います:

    1. レコード配列の各要素に対して操作を行います。
      (.records[] |)。
    2. 新しいオブジェクトを作成し、その中に指定のキーと値を設定します({EmployeeNumber: .user.id, Email: .user.account, GradeDate: .attributes[0].values[0].value, Grade: .attributes[1].values[0].value})。
    3. すべての新しいオブジェクトを包含する配列を作成します([…])。

    これにより、各レコードは新しい形式のオブジェクトに変換され、すべてのオブジェクトが配列に格納されます。それぞれのオブジェクトは EmployeeNumber、Email、GradeDate、Grade の 4つのフィールドを持ちます。

    特定の条件にマッチするレコードを選択

    また、jqは特定の条件にマッチするレコードだけを選択するためのフィルタリング機能も提供しています。たとえば、statusが0のレコードだけを選択するには、以下のようにします:

    jq '[.records[] | select(.user.status == 0) | {EmployeeNumber: .user.id, Email: .user.account, GradeDate: .attributes[0].values[0].value, Grade: .attributes[1].values[0].value}]' input.json

    このコマンドではselect(.user.status == 0)を使用して statusが0のレコードだけを選択しています。

    map関数の使い方

    関数は、配列の各要素に関数を適用して新しい配列を作成するためのものです。たとえば、各レコードのattributesの中のvaluesを取り出すには以下のようにします:

    jq '.records[] | .attributes | map(.values[].value)' input.json

    このコマンドでは、まず各レコードのattributesを取り出し(.records[] | .attributes)、それからmap関数を使って各attributesの中のvaluesのvalueを取り出しています(map(.values[].value))。

    結論

    このように、jqコマンドは非常に強力で柔軟なツールであり、JSONデータの検索やフィルタリング、変換に最適です。特にselect関数とmap関数は、データのフィルタリングや変換において非常に便利です。

    様々な場面でのデータ操作に活用してみてください。また、jqのドキュメンテーションは非常に充実していますので、さらに高度な操作を学びたい場合はそちらを参照してみてください。