shell脚本解析问题:意外的INVALID_CHARACTER(Windows cmd shell引用问题?)

时间:2019-06-22 14:11:44

标签: json bash shell parsing jq

我在做什么? 我有一个JSON文件作为sonar-report.json。我想在shell脚本中迭代sonar-report.json,以读取json的值。 要解析JSON文件,我正在使用jq https://stedolan.github.io/jq/

所以下面的代码我试图在shell脚本中执行

alias jq=./jq-win64.exe
for key in $(jq '.issues | keys | .[]' sonar-report.json); do
    echo "$key"
    line=$(jq -r ".issues[$key].line" sonar-report.json)
done

问题 当我执行此操作时,控制台给我错误:

jq: error: syntax error, unexpected INVALID_CHARACTER (Windows cmd shell quoting issues?) at <top-level>, line 1:

如果我更新上述脚本,并添加数组的静态索引,则脚本可以正常工作

alias jq=./jq-win64.exe

for key in $(jq '.issues | keys | .[]' sonar-report.json); do
    echo "$key"
    line0=$(jq -r ".issues[0].line" sonar-report.json)
    line1=$(jq -r ".issues[1].line" sonar-report.json)
done

所以最后我想要什么: 我想迭代值并在控制台中打印

alias jq=./jq-win64.exe
for key in $(jq '.issues | keys | .[]' sonar-report.json); do
    line=$(jq -r ".issues[$key].line" sonar-report.json)
    echo $line
done

所以输出应该是

15

这是我的JSON文件,为sonar-report.json

{
"issues": [
        {
            "key": "016B7970D27939AEBD",
            "component": "bits-and-bytes:src/main/java/com/catalystone/statusreview/handler/StatusReviewDecisionLedHandler.java",
            "line": 15,
            "startLine": 15,
            "startOffset": 12,
            "endLine": 15,
            "endOffset": 14,
            "message": "Use the \"equals\" method if value comparison was intended.",
            "severity": "MAJOR",
            "rule": "squid:S4973",
            "status": "OPEN",
            "isNew": true,
            "creationDate": "2019-06-21T15:19:18+0530"
        },
        {
            "key": "AWtqCc-jtovxS8PJjBiP",
            "component": "bits-and-bytes:src/test/java/com/catalystone/statusreview/service/StatusReviewInitiationSerivceTest.java",
            "message": "Fix failing unit tests on file \"src/test/java/com/catalystone/statusreview/service/StatusReviewInitiationSerivceTest.java\".",
            "severity": "MAJOR",
            "rule": "common-java:FailedUnitTests",
            "status": "OPEN",
            "isNew": false,
            "creationDate": "2019-06-18T15:32:08+0530"
        }
    ]
}

请帮助我,谢谢!

1 个答案:

答案 0 :(得分:2)

在我看来,这就像Windows / Unix行尾不兼容的实例,在jq错误92 (for Cygwin)1870 (for MSYS2)中指出。

这些错误报告中指示的任何变通办法都应该起作用,但是一旦修复程序进入发行版二进制文件(大概是v1.7),最简单的解决方案是使用新的-b命令行选项。 (该选项在最近的jq预览版本中可用;请参见上面列出的第二个错误报告):

for key in $(jq -b '.issues | keys | .[]' sonar-report.json); do
    line=$(jq -rb ".issues[$key].line" sonar-report.json)
    # I added quotes in the next line, because it's better style.
    echo "$line"
done

jq的下一个版本可用之前,或者如果您出于某种原因不想升级,一个好的解决方法是通过{ {1}}:

jq

但是,正如Cyrus的评论所指出的那样,您可能不需要在shell循环中迭代libe-bt-line,这效率极低,因为它导致多次重新分析整个JSON输入。您可以使用jq本身进行迭代,方法简单得多:

tr -d '\r'

,它将仅解析一次JSON文件,然后在文件中生成每个for key in $(jq -'.issues | keys | .[]' sonar-report.json | tr -d '\r'); do line=$(jq -r ".issues[$key].line" sonar-report.json | tr -d '\r') echo "$line" done 值。 (根据您打算对输出执行的操作,您可能仍想使用jq '.issues[].line' solar-response.json 命令行选项或其他解决方法。)