使用JQ处理cargo metadata输出时字符串拼接异常排查
路径拼接异常:/src前置的原因与解决办法
问题场景
使用JQ解析cargo metadata的JSON输出,提取项目路径后拼接/src时出现异常:本该输出C:/Users/me/project1/src,实际却变成/src C:/Users/me/project1。相关测试脚本及输出如下:
测试脚本
extractor='(?:path\+file:\/{3})(.*?)(?:#.*)?@[\d\.]+' expr=".workspace_members[] | match(\"$extractor\").captures[0].string" input='{ "workspace_members": [ "path+file:///C:/Users/me/project1#project-1@0.1.0", "path+file:///C:/Users/me/project2#project-2@0.1.0", "path+file:///C:/Users/me/project3@0.1.0", "path+file:///C:/Users/me/project4#project-4@0.1.0", "path+file:///C:/Users/me/project5#project-5@0.1.0" ] }' echo $input | jq -r "$expr" | while read cratePath; do echo "Here $cratePath/src" done
异常现象
- 未拼接
/src时的正常输出:
Here C:/Users/me/project1 Here C:/Users/me/project2 ...
- 拼接
/src后的异常输出:
/src C:/Users/me/project1 /src C:/Users/me/project2 ...
原因分析
问题根源是Windows换行符残留:JQ输出的字符串带有隐藏的\r(回车符),当read命令读取后,$cratePath实际为C:/Users/me/project1\r。拼接/src后字符串变为C:/Users/me/project1\r/src,而\r会让光标跳回行首,导致/src覆盖行开头的内容,最终呈现出异常的顺序。
解决方法
以下三种方式均可解决问题:
方法1:在JQ中直接去除回车符
修改JQ表达式,用trimstr("\r")过滤掉输出中的回车符:
expr=".workspace_members[] | match(\"$extractor\").captures[0].string | trimstr(\"\\r\")"
方法2:用tr命令过滤管道中的回车符
在JQ输出后添加tr -d '\r',直接删除所有回车符再传给循环:
echo $input | jq -r "$expr" | tr -d '\r' | while read cratePath; do echo "Here $cratePath/src" done
方法3:在循环内处理变量
在循环中用awk去除变量末尾的回车符:
echo $input | jq -r "$expr" | while read cratePath; do echo "Here $(echo "$cratePath" | awk '{sub(/\r$/,"")}1')/src" done
验证效果
修改后运行脚本,将得到正确的路径拼接结果:
Here C:/Users/me/project1/src Here C:/Users/me/project2/src ...
内容的提问来源于stack exchange,提问作者Ben
相关产品推荐
相关产品推荐

