You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在jq中正确使用select?数组遍历语法差异疑问

jq命令用法疑问解答

示例JSON

{
    "project" : [
        {
            "name" : "dungeon master",
            "date" : "2022-05-11T16:07:29.000Z",
            "status" : "active"
        },
        {
            "name" : "great gatsby",
            "date" : "2023-04-20T19:49:26.000Z",
            "status" : "active"
        },
        {
            "name" : "hundred years",
            "date" : "2022-11-29T23:37:29.000Z",
            "status" : "active"
        },
        {
            "name" : "passage to india",
            "date" : "2022-11-22T04:16:50.000Z",
            "status" : "active"
        }      
    ]
}

分步写法(成功案例)

# 逐个检查name是否包含"ma"
.project[] | .name | contains("ma")
>> true
>> false
>> false
>> false

# 筛选出符合条件的project对象
.project[] | select( .name | contains("ma"))
>> {
>>   "name": "dungeon master",
>>   "date": "2022-05-11T16:07:29.000Z",
>>   "status": "active"
>> }

# 提取符合条件的name字段
.project[] | select( .name | contains("ma")) | .name
>> "dungeon master"
# success

缩写写法(问题案例)

# 逐个检查name是否包含"ma",和分步写法效果一致
.project[].name | contains("ma")
>> true
>> false
>> false
>> false

# 错误写法:返回整个JSON对象
select(.project[].name | contains("ma"))
>> get back whole json 

# 错误写法:返回null
select(.project[].name | contains("ma")) | .name 
>> null 

问题解答

1. 为什么select(.project[].name |contains("ma"))|.name无法正常工作?错误理解是什么?

select()的作用是过滤当前输入的对象,执行select(.project[].name |contains("ma"))时,当前输入的是整个根JSON对象。.project[].name会遍历所有project的name字段,生成一组true/false结果,但select()的判断逻辑是:只要这组结果里至少有一个true,就会保留当前输入的根对象。

之后用| .name时,根JSON对象本身没有name字段,所以返回null。

核心错误是误以为select()内部的.project[].name会逐个过滤数组元素,但实际上select()是针对当前顶层输入对象(根对象)做判断,没有先把数组元素拆出来单独处理,完全搞错了过滤层级。

2. .array[].key与.array[] | .key的概念差异是什么?为何会导致写法失效?

单纯取值时,.array[].key和.array[] | .key效果一致:都会遍历数组每个元素,提取每个元素的key字段,生成对应结果序列。

但和select()结合时差异明显:

  • .array[] | .key是先把数组每个元素拆成独立对象,再对每个对象提取key;如果是.array[] | select(.key | ...),就是对每个独立数组元素做过滤,符合条件的元素会被保留。
  • 把.project[].name放在select()内部时,是在根对象层面遍历所有project的name,生成的true/false序列只会用来判断是否保留根对象,不会逐个处理数组元素。这就导致select()直接返回整个根对象,后续取.name自然得到null。

内容的提问来源于stack exchange,提问作者sylye

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 20:03:15