1. ホーム
  2. json

[解決済み] どのようにjqを使用して2つのファイルから2つのJSONオブジェクトをマージするには?

2022-04-21 19:46:52

質問

を使用しています。 jq のツール(jq-json-processor)をシェルスクリプトで実行し、jsonをパースしています。

2つのjsonファイルがあり 2つのファイルを1つのユニークなファイルに統合したい

ここにファイルの内容が表示されます。

ファイル1

{
    "value1": 200,
    "timestamp": 1382461861,
    "value": {
        "aaa": {
            "value1": "v1",
            "value2": "v2"
        },
        "bbb": {
            "value1": "v1",
            "value2": "v2"
        },
        "ccc": {
            "value1": "v1",
            "value2": "v2"
        }
    }
}

ファイル2

{
    "status": 200,
    "timestamp": 1382461861,
    "value": {
        "aaa": {
            "value3": "v3",
            "value4": 4
        },
        "bbb": {
            "value3": "v3"
        },      
        "ddd": {
            "value3": "v3",
            "value4": 4
        }
    }
}

期待される結果

{
    "value": {
        "aaa": {
            "value1": "v1",
            "value2": "v2",
            "value3": "v3",
            "value4": 4
        },
        "bbb": {
            "value1": "v1",
            "value2": "v2",
            "value3": "v3"
        },
        "ccc": {
            "value1": "v1",
            "value2": "v2"
        },
        "ddd": {
            "value3": "v3",
            "value4": 4
        }
    }
}

いろいろな組み合わせを試してみましたが、期待した結果とは異なり、次のような結果しか得られません。

{
  "ccc": {
    "value2": "v2",
    "value1": "v1"
  },
  "bbb": {
    "value2": "v2",
    "value1": "v1"
  },
  "aaa": {
    "value2": "v2",
    "value1": "v1"
  }
}
{
  "ddd": {
    "value4": 4,
    "value3": "v3"
  },
  "bbb": {
    "value3": "v3"
  },
  "aaa": {
    "value4": 4,
    "value3": "v3"
  }
}

このコマンドを使うと

jq -s '.[].value' file1 file2

解決方法は?

1.4以降では、これは * 演算子です。2つのオブジェクトが与えられたとき、再帰的にそれらをマージします。例えば

jq -s '.[0] * .[1]' file1 file2

重要 -s (--slurp) フラグを使用すると、ファイルを同じ配列に格納することができます。

得られるだろう。

{
  "value1": 200,
  "timestamp": 1382461861,
  "value": {
    "aaa": {
      "value1": "v1",
      "value2": "v2",
      "value3": "v3",
      "value4": 4
    },
    "bbb": {
      "value1": "v1",
      "value2": "v2",
      "value3": "v3"
    },
    "ccc": {
      "value1": "v1",
      "value2": "v2"
    },
    "ddd": {
      "value3": "v3",
      "value4": 4
    }
  },
  "status": 200
}

他のキーも取り除きたい場合(期待した結果のように)、一つの方法として、このようになります。

jq -s '.[0] * .[1] | {value: .value}' file1 file2

あるいは、おそらくより効率的な方法(他の値をマージしないため)。

jq -s '.[0].value * .[1].value | {value: .}' file1 file2