Ошибка разбора сценария оболочки: неожиданно INVALID_CHARACTER (проблемы с цитированием оболочки Windows cmd?) - PullRequest
1 голос
/ 22 июня 2019

Что я делаю? У меня есть один файл JSON как sonar-report.json.Я хочу повторить sonar-report.json в скрипте оболочки, чтобы прочитать значения json.Для анализа файла JSON я использую jq https://stedolan.github.io/jq/

Итак, следующий код, который я пытался выполнить в сценарии оболочки

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 Ответ

2 голосов
/ 22 июня 2019

Это выглядит для меня как пример несовместимости конца строки в Windows / Unix, указанной в ошибках jq 92 (для Cygwin) и 1870 (для MSYS2) .

Любой из обходных путей, указанных в этих отчетах об ошибках, должен работать, но как только исправление попадет в двоичный файл релиза (предположительно, v1.7), самое простое решение - использовать новый параметр командной строки -b.(Опция доступна в последних сборках jq preview; см. Второй отчет об ошибках, перечисленных выше):

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 или если вы не хотите обновлять дляпо какой-то причине, хороший обходной путь - просто удалить CR, передавая выходные данные с jq по tr -d '\r':

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, вы, вероятно, ненужно перебирать libe-bt-line в цикле оболочки, что невероятно неэффективно, так как много раз приводит к повторному анализу всего ввода JSON.Вы можете использовать сам jq для итерации, с гораздо более простым:

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

, который будет анализировать файл JSON только один раз, а затем генерировать каждое значение .line в файле.(Возможно, вы все еще хотите использовать параметр командной строки -b или другой обходной путь, в зависимости от того, что вы собираетесь делать с выводом.)

...