【问题标题】:shell script parsing issue: unexpected INVALID_CHARACTER (Windows cmd shell quoting issues?)shell 脚本解析问题:意外的 INVALID_CHARACTER(Windows cmd shell 引用问题?)
【发布时间】:2019-06-22 14:11:44
【问题描述】:

我在做什么? 我有一个 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

这是我作为 sonar-report.json 的 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"
        }
    ]
}

请帮助我,在此先感谢

【问题讨论】:

  • 请将该示例输入的所需输出添加到您的问题中。
  • 适用于 Linux。输出为15Null。您不想只使用jq '.issues[].line'
  • 我使用的是windows机器,我应该怎么做才能解决这个问题:(
  • 您使用的是哪个版本的 jq?你在什么环境下运行它? (Cygwin?Msys2?)
  • 好的,我对 Windows 上的 Git(或 Windows 上的任何东西)知之甚少,我无法测试任何解决方案,但我怀疑您可以只使用所示的 -b 选项在我的回答中。

标签: json bash shell parsing jq


【解决方案1】:

这在我看来像是 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 的下一个版本可用之前,或者如果您出于某种原因不想升级,一个好的解决方法是通过管道将jq 的输出通过tr -d '\r' 删除CR:

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

但是,正如 Cyrus 在评论中指出的那样,您可能不需要在 shell 循环中逐行迭代,这是非常低效的,因为它会导致多次重新解析整个 JSON 输入。您可以使用 jq 本身进行迭代,更简单:

jq '.issues[].line' solar-response.json

这将只解析 JSON 文件一次,然后在文件中生成每个 .line 值。 (您可能仍希望使用-b 命令行选项或其他解决方法,具体取决于您打算对输出执行的操作。)

【讨论】:

  • 谢谢,但它在 windows git bash 中不起作用 :( windows git bash 给我错误Unknown option -b 我正在使用 JQ 1.6 最新版本
  • @DupinderSingh:好的,我猜错误报告 1870 中的修复尚未进入 Windows 二进制文件。所以使用tr 解决方法:`for key in $(jq '.issues | keys | .[]' sonar-report.json | tr -d '\r');做
猜你喜欢
  • 1970-01-01
  • 2020-05-21
  • 2011-05-07
  • 2010-12-12
  • 1970-01-01
  • 1970-01-01
  • 2021-12-22
  • 2011-04-25
  • 1970-01-01
相关资源
最近更新 更多