匹配值获取id
数据:
1.
[
{"id": 1, "server": "web01"},
{"id": 2, "server": "db01"},
{"id": 3, "server": "web01"}
]
2.
[
{"id": 1, "server": "web01-prod"},
{"id": 2, "server": "WEB02"},
{"id": 3, "server": "db01"},
{"id": 4, "server": "api-web"}
]
1. 精确查询,返回所有匹配的 id(最常用)
用 --arg 把 shell 变量传进 jq,然后用 select 过滤:
server="web01" jq --arg s "$server" '.[] | select(.server == $s) | .id' data.json
如果只要第一个结果,加 first 或直接取索引:
jq --arg s "$server" '.[] | select(.server == $s) | .id' data.json | head -1 # 或者纯 jq 内处理: jq --arg s "$server" 'first(.[] | select(.server == $s) | .id)' data.json
2. 包含子串(最常用的模糊搜索)
使用 contains 函数。注意: jq 1.5+ 的 contains 是“包含”语义("web" 在 "web01-prod" 中),且是严格区分大小写的。
keyword="web" jq --arg k "$keyword" '.[] | select(.server | contains($k)) | .id' data.json
输出:1 和 4(不匹配 WEB02 因为大小写不同)
3. 正则表达式匹配(功能更强大)
用 test 函数,支持 PCRE 正则表达式。
# 匹配以 "web" 开头(不区分大小写) pattern="^web" jq --arg p "$pattern" '.[] | select(.server | test($p; "i")) | .id' data.json
-
test($p; "i")中的"i"是大小写不敏感标志。 -
如果想完全按大小写敏感匹配则去掉
"i":test($p)。
4. 忽略大小写匹配(最简单的方式)
如果不想要正则的复杂度,只需不区分大小写比较,可以用 ascii_downcase 或 ascii_upcase 把两边都转成同一种 case 再比较:
keyword="web" jq --arg k "$keyword" '.[] | select((.server | ascii_downcase) == ($k | ascii_downcase)) | .id' data.json
但这是精确相等(只是大小写不敏感),不包含子串。如果要忽略大小写且包含子串,可以组合 ascii_downcase 和 contains:
keyword="web" jq --arg k "$keyword" '.[] | select((.server | ascii_downcase) | contains($k | ascii_downcase)) | .id' data.json
这样 WEB02 也会被匹配到。
5. 搜索开头或结尾
用 startswith / endswith,同样支持大小写敏感。
prefix="web" jq --arg p "$prefix" '.[] | select(.server | startswith($p)) | .id' data.json
6. 一次返回所有匹配 id(数组形式)
若想把结果收集成 JSON 数组,用 map(select(...)):
jq --arg k "web" 'map(select(.server | contains($k)) | .id)' data.json
优雅与性能提示
-
始终用
--arg传参,避免在 shell 中拼接字符串导致注入。 -
如果要对同一份数据反复执行不同的模糊搜索,可以提前把
server字段抽取或建立倒排索引,但大多数场景下直接按上述方式过滤已经足够快且清晰。 -
test的功能最强,可以进行复杂模式匹配,比如test("^web\\\\d+")匹配 "web" 后跟数字。注意在 bash 中反斜线需要转义,或用单引号包裹 jq 程序并保持正则转义为\\d。
如果你有具体的匹配需求(比如模糊程度、大小写规则等),我可以给出更定制化的写法。
© 著作权归作者所有
下一篇: shell 数组常见用法
文章评论(0)