JQ库传递动态JSON筛选参数作为修改键的问题求解
错误原因
你之前的写法报错是因为通过--arg传入的$filter是字符串字面量,jq不会将其解析为路径选择表达式,只会当做普通字符串处理,因此无法匹配到对应字段。
解决方法
有两种常用的实现方案:
方案1:Shell层面拼接jq表达式(简单高效)
直接将过滤前缀变量作为jq表达式的一部分拼接,不需要通过--arg传参,注意Shell引号的转义规则即可:
# 定义过滤前缀,根路径为. ,Update场景为.["new_settings"] Filter="." # Filter='.["new_settings"]' # 拼接变量到jq表达式 TEMPLATE=$(cat "$FILE" | jq \ --arg _parent "$PARENT" \ --arg _job_name "$JOB_NAME" \ ' ( '"$Filter"' | .name ) |= $_job_name | ( '"$Filter"' | .schedule.pause_status) |= $_parent')
这里'"$Filter"'是Shell变量插值逻辑,会在调用jq前就把过滤前缀替换到表达式中,jq拿到的就是合法的可执行表达式,不会出现语法错误。
方案2:jq内置路径函数实现(更安全,避免注入风险)
如果过滤前缀是动态生成的不可控输入,不想使用Shell拼接,可以将路径拆分为层级数组,配合jq的setpath函数实现动态修改:
# 根路径对应空数组,Update场景对应["new_settings"] FILTER_PATH='[]' # FILTER_PATH='["new_settings"]' TEMPLATE=$(cat "$FILE" | jq \ --argjson filter_path "$FILTER_PATH" \ --arg _parent "$PARENT" \ --arg _job_name "$JOB_NAME" \ ' setpath($filter_path + ["name"]; $_job_name) | setpath($filter_path + ["schedule", "pause_status"]; $_parent)')
该方案完全在jq内部实现动态路径选择,不会存在Shell注入风险,适合生产环境使用。
内容的提问来源于stack exchange,提问作者shzyincu
相关产品推荐
相关产品推荐

