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

Bash使用jq遍历JSON时如何访问参数匹配shops.txt对应条目?

问题原因

你的原脚本存在3个核心错误:

  • 原生Bash不支持直接解析JSON对象属性,你从jq读出来的$i是字符串格式,不能用$i.store.storeName这种语法访问JSON字段
  • 原jq命令'.[.userName, .store.storeName]'的输出是拆分后的独立字段数组,已经丢失了完整的JSON对象结构
  • 没有处理store为null的情况,直接访问store.storeName会触发jq报错
最优实现方案(单jq处理,效率更高,适合大文件)

不需要嵌套Bash循环,直接一次性把shops.txt的所有门店ID读入jq做过滤,大文件场景下性能优势非常明显:

#!/bin/bash
# 读取shops.txt所有ID,转成jq可用的字符串数组,自动过滤空行
shop_list=$(jq -R -s 'split("\n") | map(select(length > 0))' shops.txt)
# 一次性过滤details.json,输出匹配的用户名和门店ID
jq -r --argjson shops "$shop_list" '
.[] | 
# 先过滤store非空的条目,避免报错
select(.store != null and .store.storeName != null) |
# 完全相等匹配,如果需要模糊匹配可以替换成下面注释的代码
select(.store.storeName | IN($shops[])) |
# 输出需要的字段
.userName, .store.storeName
' details.json

如果你需要的是模糊匹配(只要storeName包含目标门店ID就算匹配),把上面的select(.store.storeName | IN($shops[]))替换为:

select(.store.storeName as $name | any($shops[]; $name | contains(.)))
保留原循环逻辑的修改版

如果你一定要按逐行遍历shops的逻辑写,可以改成下面的版本,直接在jq层做匹配判断:

#!/bin/bash
shops="shops.txt"
while IFS= read -r currentShop || [[ -n "$currentShop" ]]
do
  # 跳过空行
  [[ -z "$currentShop" ]] && continue
  # 传入当前门店ID到jq做匹配,直接输出结果
  jq -r --arg shop "$currentShop" '
  .[] | 
  select(.store != null and .store.storeName == $shop) | 
  .userName, .store.storeName
  ' details.json
done < "$shops"

该版本逻辑简单,但如果shops.txt和details.json文件都很大,会重复调用jq多次,性能远低于上面的单jq版本。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 16:06:03