태그 보관물: command-line

command-line

jq를 사용하여 2 개의 파일에서 2 개의 JSON 객체를 병합하는 방법은 무엇입니까?

내가 사용하고 JQ의 구문 분석 JSON에 쉘 스크립트 도구 (JQ-JSON 프로세서를).

2 개의 json 파일이 있으며 하나의 고유 한 파일로 병합 하고 싶습니다.

다음은 파일 내용입니다.

file1

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

file2

{
    "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부터 이것은 이제 *운영자 와 함께 가능합니다 . 두 개의 객체가 주어지면 재귀 적으로 병합합니다. 예를 들면

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


답변

사용 jq -s add:

$ echo '{"a":"foo","b":"bar"} {"c":"baz","a":0}' | jq -s add
{
  "a": 0,
  "b": "bar",
  "c": "baz"
}

이것은 stdin의 모든 JSON 텍스트를 배열로 읽은 jq -s다음 (그렇게) “줄입니다”.

( add로 정의 def add: reduce .[] as $x (null; . + $x);입력 배열의 / 개체 값로 반복. 개체 첨가 == 병합으로 추가한다.)


답변

여전히 필요한지 누가 알지만 여기에 해결책이 있습니다.

--slurp옵션에 도달하면 쉽습니다!

--slurp/-s:
    Instead of running the filter for each JSON object in the input,
    read the entire input stream into a large array and run the filter just once.

그러면 +운영자가 원하는 작업을 수행합니다.

jq -s '.[0] + .[1]' config.json config-user.json

(참고 : 왼쪽 파일을 오른쪽 파일로 덮어 쓰는 대신 내부 개체를 병합하려면 수동으로 수행해야합니다.)


답변

다음 *은 임의의 수의 객체에 대해 재귀 적으로 작동하는 버전입니다 (사용 ).

echo '{"A": {"a": 1}}' '{"A": {"b": 2}}' '{"B": 3}' | jq --slurp 'reduce .[] as $item ({}; . * $item)'
{
  "A": {
    "a": 1,
    "b": 2
  },
  "B": 3
}


답변

첫째, { “value”: .value}는 {value}로 축약 될 수 있습니다.

둘째, –argfile 옵션 (jq 1.4 및 jq 1.5에서 사용 가능)은 –slurp 옵션을 사용할 필요가 없기 때문에 관심이있을 수 있습니다.

이들을 합치면 두 파일의 두 개체를 다음과 같이 지정된 방식으로 결합 할 수 있습니다.

$ jq -n --argfile o1 file1 --argfile o2 file2 '$o1 * $o2 | {value}'

‘-n’플래그는 입력이 여기에있는 –argfile 옵션에서 나오기 때문에 jq에게 stdin에서 읽지 않도록 지시합니다.


답변

이것은 명령에 지정된 파일을 병합하는 데 사용할 수 있습니다.

jq -rs 'reduce .[] as $item ({}; . * $item)' file1.json file2.json file3.json ... file10.json

또는 이것은 여러 파일에 대해

jq -rs 'reduce .[] as $item ({}; . * $item)' ./*.json


답변