【问题标题】:jq filter for object with target value or key is not exist具有目标值或键的对象的 jq 过滤器不存在
【发布时间】:2021-07-05 07:08:20
【问题描述】:

我有 jsonlines 数据,我想找到 1. value is empty object 或 2. key is not exist 。在下面的示例中,我想知道 .items.spec.resource={} 或 .items.spec.limits|requests which key 不存在的项目的结果。

data='{"items":[{"metadata":{"name":"pod01"},"spec":{"containers":[{"name":"con01_01","resources":{"limits":{"cpu":"100m"},"requests":{"cpu":"100m"}}},{"name":"con01_02","resources":{"limits":{"cpu":"100m"},"requests":{"cpu":"100m"}}}]}},{"metadata":{"name":"pod02"},"spec":{"containers":[{"name":"con02_01","resources":{"limits":{"cpu":"100m"},"requests":{"cpu":"100m"}}},{"name":"con02_02","resources":{"limits":{"cpu":"100m"}}}]}},{"metadata":{"name":"pod03"},"spec":{"containers":[{"name":"con03_01","resources":{"limits":{"cpu":"100m"},"requests":{"cpu":"100m"}}},{"name":"con03_02","resources":{}}]}}]}'
list=$(echo $data | jq '.items[] | select(.spec.containers[].resources.requests == null or  .spec.containers[].resources.limits == null or .spec.containers[].resources == {})')
echo $list 

结果来了

{ 
  "metadata": { "name": "pod02" }, 
  "spec": { 
    "containers": [ 
      { "name": "con02_01", 
        "resources": { 
                       "limits": { "cpu": "100m" }, 
                       "requests": { "cpu": "100m" } 
                     } 
      }, 
      { "name": "con02_02", 
        "resources": { 
                       "limits": { "cpu": "100m" } 
                     } 
      } 
    ] 
  } 
} 
{ 
  "metadata": { "name": "pod03" },
  "spec": {
    "containers": [ 
      { 
        "name": "con03_01", 
        "resources": { 
                       "limits": { "cpu": "100m" }, 
                       "requests": { "cpu": "100m" } 
                     } 
      }, 
      { "name": "con03_02", 
        "resources": {} 
      } 
    ] 
  } 
} 

{ 
  "metadata": { "name": "pod03" }, 
  "spec": { 
    "containers": [ 
      { "name": "con03_01", 
        "resources": { 
                        "limits": { "cpu": "100m" }, 
                        "requests": { "cpu": "100m" } 
                     } 
      }, 
      { "name": "con03_02", 
        "resources": {} 
      } 
    ] 
  } 
} 
  
{ 
  "metadata": { "name": "pod03" }, 
  "spec": { 
    "containers": [ 
      { "name": "con03_01", 
        "resources": { 
                        "limits": { "cpu": "100m" }, 
                        "requests": { "cpu": "100m" } 
                      } 
      }, 
      { "name": "con03_02", 
        "resources": {} 
      } 
    ] 
  } 
}

repeat部分没看懂,估计是条件的关系,怎么才能得到上面条件的部分,想过滤metadata和spec.containers中满足条件的部分。

【问题讨论】:

  • 你想要pod名称还是容器名称作为输出?
  • 是的,我想要 pod 名称和容器名称作为输出

标签: json select key jq jsonlines


【解决方案1】:

根据您的解释性评论,您似乎可以使用 jq "$-variables" 实现您想要的:

jq -c '
.items[]
| .metadata.name as $podname
| .spec.containers[] 
| select(.resources.requests == null or 
         .resources.limits == null or 
         .resources == {})
| [$podname, .name]
'

使用您的数据,上述产生的输出将是:

["pod02","con02_02"]
["pod03","con03_02"]

简化

第三个条件(.resources == {})的测试其实是多余的,所以上面的jq过滤器相当于:

.items[]
| .metadata.name as $podname
| .spec.containers[] 
| select(.resources | (.requests == null or .limits == null ))
| [$podname, .name]

存在密钥

要检查密钥是否存在,通常使用has/1 是合适的,因为{} | .key 的计算结果为null。因此,您可能希望将上面的 select() 替换为:

select( any(.resources | has("requests", "limits"); not) )

【讨论】:

  • 感谢您提供此信息。这对我帮助很大。
猜你喜欢
  • 2021-12-30
  • 2019-04-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多