jq 过滤器如果包含列表中的元素则删除字段值

问题描述 投票:0回答:1

这有点类似于:jq:如何根据内部数组中的值过滤对象数组?但扩展了

我有一个想要过滤掉的值列表,但它不是 1:1 匹配。它包含匹配项。

有这样的输入(来自文件或管道):

{
  "namespace": "namespace1",
  "name": "some-pod1",
  "images": [
    "acr1.azurecr.io/some_project/some_project_image@sha256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "docker.io/istio/proxyv2@sha256:57621adeb78e67c52e34ec1676d1ae898b252134838d60298c7446d0964551cc"
  ],
  "initImages": [
    "docker.io/istio/proxyv2@sha256:57621adeb78e67c52e34ec1676d1ae898b252134838d60298c7446d0964551cc"
  ]
}
{
  "namespace": "namespace1",
  "name": "some-pod2",
  "images": [
    "acr1.azurecr.io/some_project/some_project_image@sha256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "docker.io/istio/proxyv2@sha256:57621adeb78e67c52e34ec1676d1ae898b252134838d60298c7446d0964551cc"
  ],
  "initImages": [
    "docker.io/istio/proxyv2@sha256:57621adeb78e67c52e34ec1676d1ae898b252134838d60298c7446d0964551cc"
  ]
}

还有这样的查询

jq -r '.[] as $pods | ["kube-system", "kube-public", "gatekeeper-system", "istio-system", "istio-operator"] as $excludedNamespaces | ["istio", "registry.k8s", "mcr.microsoft.com", "azurecr.io"] as $excludedImages | $pods | select((.initImages[] | contains("docker.io")) or (.images[] | contains("docker.io"))) | select(.namespace as $in | $excludedNamespaces | index($in) | not) | del(.images | select(contains($excludedImages))) ' pods.json

我需要做类似的事情:

del(.images | select(contains("istio") or select(contains("registry.k8s") or ...))

因为我已经有了 $excludedImages 列表,所以我想处理它,如果我需要更改它,那么我可以在一个地方执行此操作。我按照上面的方法尝试将整个列表传递给 contains 函数,但它没有按预期工作。我总是在输出中看到“istio”图像。

我只想从列表中删除这些值。如果图像列表为空(同样适用于 initImages),那么我想从输出中删除整个对象。

问题是 docker 在 docker hub 上启用了一些限制,我想找到尚未迁移到我们自己的注册表而不是直接迁移到 docker hub 的 pod。但有一些镜像被排除在限制之外,例如 istio。它可以直接从 docker hub 拉取。这就是整个想法。

因此,我准备了要排除的命名空间和要排除的图像的列表。命名空间是 1:1 匹配,所以没有问题,但是图像......它们包含这些哈希值,所以它们总是会改变,我无法直接提供它。

我们将非常感谢您的帮助。

json select jq contains del
1个回答
0
投票

我只想从列表中删除这些值。如果图像列表为空(同样适用于 initImages),那么我想从输出中删除整个对象。

对于

select
内的
del
条件,请在所有项目上使用
any
,而不是与
or
单独分离。要在空数组的情况下删除整个对象,一个简单的
select
就足够了,它定义了要保留的内容。在这里,我还包含了
any
,因为如果
images
initImages
中的任一数组非空(即仅在两者都为空时才删除),您可能希望保留对象。

请注意,不幸的是,示例输入中的所有项目都包含

"istio"
"azurecr.io"
,因此最终这两个对象都将被删除。如果您更新示例数据以更好地举例说明不同的情况,我也会对此响应进行调整。

["istio", "registry.k8s", "mcr.microsoft.com", "azurecr.io"] as $excludedImages
| del(.images[], .initImages[] | select(any(.; contains($excludedImages[]))))
| select(any(.images, .initImages; . != []))

演示

© www.soinside.com 2019 - 2024. All rights reserved.