如何在Bash中拆分JSON对象字符串并实现双层循环处理
问题描述
我需要读取一个JSON文件并对每个对象执行命令,JSON格式如下:
[ { "table": "table_name", "items": [ { "Key": "k1", "Value": "v1" }, { "Key": "k2", "Value": "v2" } ] }, {...} ]
目前通过Bash脚本读取JSON内容,结合表名传给Python脚本获取对应items。现在变量items中存储着类似{ "Key": "k1", "Value": "v1" }, { "Key": "k2", "Value": "v2" }的字符串,希望拆分该字符串以单独获取每个对象,让以下循环:
for item in $items; do echo "Item: $item" done
能输出:
Item: { "Key": "k1", "Value": "v1" } Item: { "Key": "k2", "Value": "v2" }
整体需要两层循环:一层遍历表,一层遍历JSON对象并将其作为参数。当前代码如下:
当前Bash代码
tables=$(echo "$data" | grep -o '"table": *"[^"]*' | grep -o '"[^"]*$' | awk -F '"' '{print $2}') for table in $tables; do items=$(echo "$data" | python parse_json.py "$table" "$data") echo "$table ${items[@]}" IFS=',' read -r -a json_objects <<< "${items%,}" done
当前Python代码
import sys, json table_name = sys.argv[1] data = json.loads(sys.argv[2]) # Extract items for the current table items = [item for entry in data if entry['table'] == table_name for item in entry['items']] # Output items as JSON strings #print([f"{item}," if i != len(items) - 1 else item for i, item in enumerate(items)]) for i, item in enumerate(items): print(item) if i == len(items)-1 else print(f"{item},")
解决方案
核心问题在于用逗号分割JSON对象不可靠(若对象内部包含逗号会出错),更稳妥的方式是让Python输出每个JSON对象单独一行,再由Bash按行读取处理。
1. 修改Python脚本
使用json.dumps()将每个item转为标准JSON字符串,每行输出一个:
import sys, json table_name = sys.argv[1] data = json.loads(sys.argv[2]) # 提取对应表的items items = [item for entry in data if entry["table"] == table_name for item in entry["items"]] # 每个item转为JSON字符串后单独输出一行 for item in items: print(json.dumps(item))
2. 修改Bash脚本
直接读取Python输出的每一行作为单个item,避免字符串分割的问题:
# 推荐用jq提取表名(比grep/awk更可靠,需确保已安装jq) tables=$(echo "$data" | jq -r '.[].table') for table in $tables; do # 读取Python输出的每一行,循环处理每个item echo "Processing table: $table" echo "$data" | python parse_json.py "$table" "$data" | while read -r item; do echo "Item: $item" # 这里可添加要执行的命令,例如: # your_command --table "$table" --item "$item" done done
说明
json.dumps()确保输出标准JSON格式,即使item内部包含逗号或引号也能正确处理。while read -r item按行读取,每行对应一个完整的JSON对象,完美匹配需求。- 若无法使用jq,可保留原有的grep/awk提取表名的方式,但jq处理JSON更稳定,建议优先使用。
完整示例运行
假设JSON文件名为data.json,Bash脚本中先读取文件内容:
data=$(cat data.json) # 执行上述循环逻辑
运行后输出:
Processing table: table_name Item: {"Key": "k1", "Value": "v1"} Item: {"Key": "k2", "Value": "v2"}
内容的提问来源于stack exchange,提问作者strojan
相关产品推荐
相关产品推荐

