jq:过滤嵌套数组对象

jq: filter nested array objects

这是我的文件:

[
  {
    "id": "3e67b455-8cdb-4bc0-a5e1-f90253870fc9",
    "identifier": [
      {
        "system": {
          "value": "urn:oid:2.16.724.4.9.20.91-INVENTAT"
        },
        "value": {
          "value": "04374"
        }
      },
      {
        "system": {
          "value": "urn:oid:2.16.724.4.9.20.2-INVENTAT"
        },
        "value": {
          "value": "INFP3"
        }
      },
      {
        "system": {
          "value": "urn:oid:INVENTAT"
        },
        "value": {
          "value": "CBOU035"
        }
      }
    ]
  },
  {
    "id": "0f22e5ff-70bc-457f-bdaf-7afe86d478de",
    "identifier": [
      {
        "system": {
          "value": "urn:oid:2.16.724.4.9.20.91-INVENTAT"
        },
        "value": {
          "value": "04376"
        }
      },
      {
        "system": {
          "value": "urn:oid:2.16.724.4.9.20.2-INVENTAT"
        },
        "value": {
          "value": "INF07"
        }
      },
      {
        "system": {
          "value": "urn:oid:INVENTAT"
        },
        "value": {
          "value": "S527918"
        }
      }
    ]
  },
  {
    "id": "a1ea574c-438b-443c-ad87-d31d09d581f0",
    "identifier": [
      {
        "system": {
          "value": "urn:oid:2.16.724.4.9.20.91-INVENTAT"
        },
        "value": {
          "value": "08096"
        }
      },
      {
        "system": {
          "value": "urn:oid:2.16.724.4.9.20.2-INVENTAT"
        },
        "value": {
          "value": "INF04"
        }
      },
      {
        "system": {
          "value": "urn:oid:INVENTAT"
        },
        "value": {
          "value": "5635132"
        }
      }
    ]
  }
]

我需要过滤 .identifier,其中 system.value="urn:oid:2.16.724.4.9.20.91-INVENTAT"system.value="urn:oid:2.16.724.4.9.20.2-INVENTAT",然后选择 .value.value

期望的输出:

[
  {
    "id": "3e67b455-8cdb-4bc0-a5e1-f90253870fc9",
    "oid1": "04374",
    "oid2": "INFP3"
  },
  {
    "id": "0f22e5ff-70bc-457f-bdaf-7afe86d478de",
    "oid1": "04376",
    "oid2": "INF07"
  },
  {
    "id": "a1ea574c-438b-443c-ad87-d31d09d581f0",
    "oid1": "08096",
    "oid2": "INF04"
  }
]

我试过:

map(
    {
        id,
        oid1: select(.identifier?[]?.system.value == "urn:oid:2.16.724.4.9.20.91-INVENTAT") | .identifier[].value.value,
        oid2: select(.identifier?[]?.system.value == "urn:oid:2.16.724.4.9.20.2-INVENTAT") | .identifier[].value.value
    }
)

但输出不是我需要的:您可以在 this jqplay.

上找到它

有什么想法吗?

这使用 IN 检查您的查询字符串,并使用数组 with_entriesoid 键生成索引。

jq '
  map({id} + (.identifier | map(select(IN(.system.value; 
    "urn:oid:2.16.724.4.9.20.91-INVENTAT",
    "urn:oid:2.16.724.4.9.20.2-INVENTAT"
  )).value.value) | with_entries(.key |= "oid\(. + 1)")))
'
[
  {
    "id": "3e67b455-8cdb-4bc0-a5e1-f90253870fc9",
    "oid1": "04374",
    "oid2": "INFP3"
  },
  {
    "id": "0f22e5ff-70bc-457f-bdaf-7afe86d478de",
    "oid1": "04376",
    "oid2": "INF07"
  },
  {
    "id": "a1ea574c-438b-443c-ad87-d31d09d581f0",
    "oid1": "08096",
    "oid2": "INF04"
  }
]

Demo

这里有一个 ruby 可以做到这一点:

ruby -r json -e '
def walk(x, filt)
    rtr=[]
    rep=["uab", "ub"]
    x.each{|e| 
        rd={"id"=>e["id"]}.merge(
        e["identifier"].
            filter{|ea| filt.include?(ea["system"]["value"])}.
            map.with_index(1){|di, i| ["#{rep[i%2]}", "#{di["value"]["value"]}"]}.to_h)
        rtr << rd       
        }
    rtr
end
    
data=JSON.parse($<.read)
puts walk(data, ["urn:oid:2.16.724.4.9.20.91-INVENTAT", "urn:oid:2.16.724.4.9.20.2-INVENTAT"]).to_json
' file 

打印:

[{"id":"3e67b455-8cdb-4bc0-a5e1-f90253870fc9","ub":"04374","uab":"INFP3"},{"id":"0f22e5ff-70bc-457f-bdaf-7afe86d478de","ub":"04376","uab":"INF07"},{"id":"a1ea574c-438b-443c-ad87-d31d09d581f0","ub":"08096","uab":"INF04"}]