如何在jq中使用含斜线的变量作为键并删除对应节点?
在jq中处理含变量的带斜线JSON路径的正确方式
问题场景
你尝试用jq删除路径包含斜线(特殊字符)的JSON节点,以下两种操作可正常运行:
- 直接使用带引号的特殊字符路径:
cat package-lock.json | jq 'del(.packages."foo/bar")' > package-lock-new.json - 从环境变量传入参数:
export ROOT=packages cat package-lock.json | jq --arg ROOT "$ROOT" 'del(.$ROOT."foo/bar")' > package-lock-new.json
但将两者结合,在带引号的路径中展开环境变量时,命令无法正常工作:
export BAR=bar cat package-lock.json | jq --arg BAR "$BAR" 'del(.packages."foo/$BAR".version)' > package-lock-new.json
解决方案
问题根源在于:单引号包裹的jq表达式中,shell变量不会被解析,同时jq也无法在带引号的对象键名里直接识别内部变量。你可以通过以下两种方式解决:
方式1:在jq内部拼接键名
使用字符串拼接生成完整键名,配合方括号索引语法访问节点:
export BAR=bar cat package-lock.json | jq --arg BAR "$BAR" 'del(.packages["foo/" + $BAR].version)' > package-lock-new.json
方式2:提前在shell层面拼接完整路径
如果路径结构更复杂,可先在shell中拼接好完整的带斜线路径,再传给jq:
export FULL_KEY="foo/bar" cat package-lock.json | jq --arg key "$FULL_KEY" 'del(.packages[$key].version)' > package-lock-new.json
核心原理
- 当JSON键名包含特殊字符(如斜线)或需要动态生成时,必须使用
[]索引语法,不能直接用.点语法访问。 - jq表达式用单引号包裹时,shell不会展开其中的变量,必须通过
--arg将外部变量传入jq环境,再在jq内部进行变量操作。
内容的提问来源于stack exchange,提问作者sprijk
相关产品推荐
相关产品推荐

