JQ скрипт с обратной галочкой в ​​значении JSON - PullRequest
0 голосов
/ 28 июня 2018

Я использую jq внутри скрипта bash, чтобы проанализировать JSON, возвращенный службой API REST

Это мой код (получение значения .count)

# getAPIId
# Parse the answer of query API to get the API ID (checking version name)
# return (echo to stdout) the APIID
function getAPIId() {
    local apiId
    local version
    local -i count          

    if [ -z $1 ]
    then
        echo "Use: getAPIId \$apiQuery" >&2
        exit 1
    else    
        # Parse answer to API info
        count=$(echo "$1"|jq -r '.count')
        if [ "$count" == "0" ]
        then
            echo $1 >&2
            echo "ERROR: Cannot find an API called ${APINAME}" >&2
            return 1
        else
            for ((i=0; i<count; i++))
            do
                version=$(echo $1|jq -r '.list['$i'].version')
                if [ "$APIVERSION" == "$version" ] && [ "$APINAME" == "$name" ]
                then
                    apiId=$(echo $1|jq -r '.list['$i'].id')
                    echo "$apiId"
                    return 0
                fi
            done
        fi
    fi
    return 1

}

Это файл JSON, который я пытаюсь проанализировать

{"count":1,"next":"","previous":"","list":[{"id":"6d2822e5-a90d-4738-b7b7-ef7d7848cb48","name":"SwaggerPetstore",
"description":"`special key`","context":"/v2","version":"1.0.0","provider":"admin","status":"CREATED","thumbnailUri":null}],"pagination":{"total":1,"offset":0,"limit":25}}

Как видите, описание поля содержит значение обратной галочки. В этом случае jq завершается ошибкой и возвращает пустую строку (как не найденное значение для count)

Как можно избежать проблемы с backtick?

1 Ответ

0 голосов
/ 28 июня 2018

jq не имеет никаких проблем с обратными галочками в литеральных значениях. Вы можете видеть это следующим образом:

$ jq '.value' <<<'{"otherKey": "`otherValue`", "value": "desired value `with backticks`"}'
"desired value `with backticks`"

Что касается кода, приведенного в вопросе, то он сильно усложнен. Вместо того, чтобы разбираться в том, что может быть не так, рассмотрите следующую замену (которая вообще не должна читать count и вызывает jq только один раз):

# Aside: Using all-caps names is bad practice. Don't do this.
APINAME=SwaggerPetstore
APIVERSION=1.0.0

getAPIId() {
  [[ $1 ]] || { echo 'Usage: getAPIId "$json"' >&2; return 1; }
  jq -er \
       --arg target_name "$APINAME" \
       --arg target_version "$APIVERSION" '
    .list[] |
    select(.name == $target_name) |
    select(.version == $target_version) |
    .id' <<<"$1"
}

... возвращается, когда вызывается следующим образом:

s='{
  "count": 1,
  "next": "",
  "previous": "",
  "list": [
    {
      "id": "6d2822e5-a90d-4738-b7b7-ef7d7848cb48",
      "name": "SwaggerPetstore",
      "description": "`special key`",
      "context": "/v2",
      "version": "1.0.0",
      "provider": "admin",
      "status": "CREATED",
      "thumbnailUri": null
    }
  ],
  "pagination": {
    "total": 1,
    "offset": 0,
    "limit": 25
  }
}'

getAPIId "$s"; echo "Exit status is $?" >&2

... правильный результат:

6d2822e5-a90d-4738-b7b7-ef7d7848cb48
Exit status is 0

... тогда как, если мы запустим его снова с неверным именем или версией для поиска:

APINAME=NotFound getAPIId "$s"; echo "Exit status is $?" >&2

... правильно отражает это:

Exit status is 4
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...