서로 다른 키의 JSON 배열 병합

서로 다른 키의 JSON 배열 병합

배열이 포함된 2개의 JSON 파일이 있습니다(bash에서 컬을 사용하여 RestAPI에서 추출됨). 두 파일 모두 .result상단에 유지해야 하는 개체가 있는 배열입니다. 첫 번째 필드에는 하나의 필드와 빈 필드를 .name포함하여 많은(100개 이상의) 다른 필드가 있습니다. .ip_address두 번째 항목에는 인터페이스, IP 주소, 다양한 필드 이름의 이름(키) 등의 추가 정보가 포함되어 있습니다. 첫 번째 파일의 키는 두 번째 파일의 키와 다르지만 관련이 있어야 합니다(물론 이전에 키 필드 이름을 변경할 수 있었고 키에 대한 데이터는 일반적으로 대소문자가 혼합되어 있습니다).

ip_address.name첫 번째 JSON을 동일한 필드로 덮어쓰고 추가 데이터를 추가할 수 있도록 병합하고 싶습니다 .

나는 그것이 배열 곱셈 또는 감소 및 덧셈이라는 것을 알고 있지만 내가 찾은 예제에 따르면 올바른 결과를 얻을 수 없습니다. 해결책을 주시면 감사하겠습니다.

섬기는 사람:

{
  "result": [
    {
      "os": "Microsoft Windows Server 2019 Standard",
      "name": "SERVER1",
      "ip_address": ""
    },
    {
      "os": "Microsoft Windows Server 2019 Standard",
      "name": "SERVER2",
      "ip_address": ""
    },
    {
      "os": "Microsoft Windows Server 2019 Standard",
      "name": "server3",
      "ip_address": ""
     },
    {
      "os": "Microsoft Windows Server 2016 Standard",
      "name": "server4",
      "ip_address": ""
     }
  ]
}

ips.txt

{
  "result": [
    {
      "interface": "Intel Wireless-AC 9560 160MHz",
      "cmdb.name": "server1",
      "ip_address": "10.0.0.10"
    },
    {
      "interface": "Wi-Fi",
      "cmdb.name": "server2",
      "ip_address": "10.0.0.10"
    },
    {
      "interface": "Intel Dual Band Wireless-AC 8265",
      "cmdb.name": "server4",
      "ip_address": "10.0.0.10"
    }
  ]
}

서버 데이터의 예상 출력은 다음과 같습니다.

{
  "result": [
    {
      "os": "Microsoft Windows Server 2019 Standard",
      "name": "SERVER1",
      "interface": "Intel Wireless-AC 9560 160MHz",
      "ip_address": "10.0.0.10"
    },
    {
      "os": "Microsoft Windows Server 2019 Standard",
      "name": "SERVER2",
      "interface": "Wi-Fi",
      "ip_address": "10.0.0.10"
    },
    {
      "os": "Microsoft Windows Server 2019 Standard",
      "name": "server3",
      "ip_address": ""
     },
    {
      "os": "Microsoft Windows Server 2016 Standard",
      "name": "server4",
      "interface": "Intel Dual Band Wireless-AC 8265",
      "ip_address": "10.0.0.10"
     }
  ]
}

답변1

다음은 관계형 JOIN()함수를 사용하여 키(서버)와 키(IP)의 소문자 변형에 대해 동일한 jq두 배열의 요소를 결합합니다 . result또한 IP 파일 배열에 인덱스를 구축하는 데에도 사용됩니다. 이 함수는 함수를 사용하여 병합된 일치하는 개체(예에서는 쌍)의 배열을 제공합니다. 결합 및 병합 후 및 키를 모두 포함하는 객체가 남으므로 각 객체에서 후자를 제거합니다.namecmdb.nameINDEX()resultJOIN()addnamecmdb.name

jq '.result = [JOIN(INDEX(input.result[]; ."cmdb.name"|ascii_downcase); .result[]; .name|ascii_downcase) | add | del(."cmdb.name")]' servers.json ips.json

표현식의 jq형식은 다음과 같습니다.

.result =
  [
    JOIN(
      # index on the second file's .cmdb.name key in each result object
      INDEX(
        input.result[];
        ."cmdb.name" | ascii_downcase
      );
      .result[];             # join on the first file's result objects
      .name | ascii_downcase # match using the .name key
    )
    | add               # merge the matched objects
    | del(."cmdb.name") # delete that key we don't want
  ]

결과:

{
  "result": [
    {
      "os": "Microsoft Windows Server 2019 Standard",
      "name": "SERVER1",
      "ip_address": "10.0.0.10",
      "interface": "Intel Wireless-AC 9560 160MHz"
    },
    {
      "os": "Microsoft Windows Server 2019 Standard",
      "name": "SERVER2",
      "ip_address": "10.0.0.10",
      "interface": "Wi-Fi"
    },
    {
      "os": "Microsoft Windows Server 2019 Standard",
      "name": "server3",
      "ip_address": ""
    },
    {
      "os": "Microsoft Windows Server 2016 Standard",
      "name": "server4",
      "ip_address": "10.0.0.10",
      "interface": "Intel Dual Band Wireless-AC 8265"
    }
  ]
}

관련 정보