Windows Server 2016 Git Bash下JQ循环脚本执行异常求助
问题描述
在Windows Server 2016的Git Bash环境中运行以下JQ过滤脚本时,仅部分执行正常:多人员条目场景下仅最后一个条目能正确输出,单条目场景则完全正常。脚本内容如下:
FILENAME="c:\Test\output4p.json" for i in $(cat "$FILENAME" | jq -r .[].personnelNumber); do echo $i echo jq '.[] | select(.personnelNumber=="'$i'")' "$FILENAME" echo done
移除脚本中JQ命令的-r参数后,出现明确的语法错误,示例错误信息如下:
$ "C:\TEST\echo.sh" "3633014" jq: error: syntax error, unexpected LITERAL, expecting ';' or ')' (Windows cmd shell quoting issues?) at <top-level>, line 1: ") 33014" jq: 1 compile error "3634594" jq: error: syntax error, unexpected LITERAL, expecting ';' or ')' (Windows cmd shell quoting issues?) at <top-level>, line 1: ") 34594" jq: 1 compile error "3634708" jq: error: syntax error, unexpected LITERAL, expecting ';' or ')' (Windows cmd shell quoting issues?) at <top-level>, line 1: ") 34708" jq: 1 compile error "3634847" jq: error: syntax error, unexpected LITERAL, expecting ';' or ')' (Windows cmd shell quoting issues?) at <top-level>, line 1: .[] | select(.personnelNumber==""3634847"") jq: 1 compile error
需求目标:基于personnelNumber构建循环,逐个输出对应的完整数组对象,后续计划将代码整合到curl命令中。
解决方案
问题根源是Git Bash与Windows的换行符冲突,以及shell变量替换时的引号嵌套语法错误,以下两种方法可解决:
方法1:修复shell循环的核心问题
修改脚本,用while read替代for循环处理换行,同时用jq --arg传递变量避免引号冲突:
FILENAME="c:\Test\output4p.json" # 用while read处理换行,规避Git Bash下CRLF换行符残留的问题 jq -r .[].personnelNumber "$FILENAME" | while read -r i; do echo "$i" echo # 用--arg传递变量,避免直接拼接导致的引号嵌套错误 jq --arg num "$i" '.[] | select(.personnelNumber == $num)' "$FILENAME" echo done
关键改进点:
- 替换
for循环为while read -r:解决Windows换行符(CRLF)在Git Bash中导致变量末尾残留\r的问题,这是之前错误中出现") 33014"这类异常内容的直接原因。 - 使用
jq --arg传递变量:彻底避免在jq脚本中直接拼接shell变量引发的引号嵌套语法错误,同时提升代码安全性与兼容性。
方法2:全程用JQ处理(更高效)
如果不需要单独输出每个personnelNumber,可以直接用JQ一次性处理所有条目,完全规避shell循环的跨环境问题:
# 按需求输出每个条目(含personnelNumber和完整对象) jq '.[] | .personnelNumber, .' "c:\Test\output4p.json"
如果需要和原脚本一致的分隔格式,可通过JQ的字符串拼接实现:
jq '.[] | "\(.personnelNumber)\n\n\(.)\n"' "c:\Test\output4p.json"
这种方式无需shell循环,完全由JQ处理,更适合后续整合到curl命令中。
内容的提问来源于stack exchange,提问作者Randy
相关产品推荐
相关产品推荐

