如何修复Bash脚本循环修改JSON文件时的jq编译错误
修复Bash脚本中jq的变量引用错误
原始JSON文件(data.json)
{ "A": "10", "BB": { "m": "refresh", "t": 1100, "tt": 1, "pp": 0, "fp": 0 }, "ss": "1", "ZZZ": { "0": { "np": 45, "sh": "True", "ni": 32, "ft": "False", "te": "True", "t": 23, "mm": 21 } }, "nr": "564" }
任务需求
循环1到100次:
- 第1次循环:将ZZZ中的键"0"改为当前i值1,写入data.json
- 第2次循环:读取data.json,将ZZZ中的键"1"改为当前i值2
- 以此类推直到循环结束
用户编写的错误脚本
#!/bin/bash # Input JSON file and output directory input_file="data.json" # Loop from i=1 to 100 for ((i=1; i<=100; i++)); do # Copy the original JSON to a new file cp "$input_file" "output.json" # Modify the JSON file with jq jq --argjson new_i "$i" '.ZZZ[$new_i] = .ZZZ[$i - 1] | del(.ZZZ[$i - 1])' "output.json" > "temp.json" # Move the modified JSON back to the original file mv "temp.json" "data.json" done
错误信息
jq: 2 compile errors jq: error: $i is not defined at <top-level>, line 1: .ZZZ[$new_i] = .ZZZ[$i - 1] | del(.ZZZ[$i - 1])
错误原因
jq无法直接识别Bash变量$i,只有通过--arg或--argjson显式传递的变量才能在jq表达式中使用。另外脚本里的cp操作属于冗余步骤,没必要每次循环复制原文件。
修复后的脚本
#!/bin/bash input_file="data.json" for ((i=1; i<=100; i++)); do # 在Bash中计算前一个键的数值 prev_i=$((i-1)) # 将新键和旧键都传递给jq jq --argjson new_key "$i" --argjson prev_key "$prev_i" \ '.ZZZ[$new_key] = .ZZZ[$prev_key] | del(.ZZZ[$prev_key])' "$input_file" > temp.json mv temp.json "$input_file" done
关键说明
- 先在Bash环境中计算出前一个键值
prev_i,再通过--argjson传递给jq,确保jq能识别这个变量。 - 使用
--argjson保证传递的是数值类型,和JSON中ZZZ的键类型匹配(jq会自动处理数值到字符串键的转换)。 - 移除冗余的文件复制操作,直接读取原文件修改后覆盖,提升脚本效率。
内容的提问来源于stack exchange,提问作者plpm
相关产品推荐
相关产品推荐

