Bash中用引号替代空格分隔命令数组的方法(Mario Maker场景)
解决Bash脚本处理JSONL数据时字段空格拆分问题
核心问题根源
Bash数组默认以空白字符(空格、制表符、换行)作为分隔符,当课程名称这类带空格的字段被直接拆分时,会被拆分成多个数组元素,导致数据错乱。要解决这个问题,关键是确保每个字段作为数组的单个元素被处理,避免手动拆分空白字符。
最佳解决方案:用jq提取并安全处理字段
jq是专门处理JSON的工具,能精准提取字段并保留原始格式,避免Bash的空白拆分问题。以下是修改后的脚本示例:
基础版脚本(直接提取输出)
#!/bin/bash # 读取JSONL文件,替换为你的文件路径 JSONL_FILE="smb1_levels.jsonl" while IFS= read -r json_line; do # 用jq提取字段,保留原始空格 level_id=$(echo "$json_line" | jq -r '.id') course_name=$(echo "$json_line" | jq -r '.course_name') creator_name=$(echo "$json_line" | jq -r '.creator_name') # 带引号输出,避免空格导致的错乱 echo "\"$level_id\" \"$course_name\" \"$creator_name\"" # 存入数组(每个字段作为独立元素) level_data+=("$level_id" "$course_name" "$creator_name") done < "$JSONL_FILE" # 验证数组内容(每3个元素为一组) for ((idx=0; idx<${#level_data[@]}; idx+=3)); do printf "关卡ID: %s\n课程名称: %s\n创作者: %s\n---\n" \ "${level_data[idx]}" "${level_data[idx+1]}" "${level_data[idx+2]}" done
整合ID转换脚本的版本
如果需要调用Python脚本转换关卡ID,直接在提取后加入转换步骤即可:
#!/bin/bash JSONL_FILE="smb1_levels.jsonl" CONVERT_SCRIPT="convert_id.py" while IFS= read -r json_line; do raw_id=$(echo "$json_line" | jq -r '.id') # 调用Python脚本转换ID converted_id=$(python3 "$CONVERT_SCRIPT" "$raw_id") course_name=$(echo "$json_line" | jq -r '.course_name') creator_name=$(echo "$json_line" | jq -r '.creator_name') echo "转换后ID: \"$converted_id\" | 课程名: \"$course_name\" | 创作者: \"$creator_name\"" done < "$JSONL_FILE"
为什么之前的方法失效?
- 循环追加数组时,如果没有用引号包裹字段值,带空格的字符串会被Bash拆分成多个数组元素。
eval虽然能强制解析引号,但存在安全风险(比如字段包含特殊字符时会执行意外命令),且容易出现解析错误,不建议使用。
额外优化:用制表符分隔批量处理
如果JSONL文件较大,可让jq输出制表符分隔的字段,进一步避免字符冲突:
jq -r '[.id, .course_name, .creator_name] | @tsv' "$JSONL_FILE" | while IFS=$'\t' read -r id name creator; do echo "\"$id\" \"$name\" \"$creator\"" done
内容的提问来源于stack exchange,提问作者Jonah Alexander
相关产品推荐
相关产品推荐

