JQ用“-”解析字符串

lis*_*4ok 2 shell json jq

我的JSON:

{
    "projects": {
        "api-client": {
            "status": "false",
            "when": "19-01-2016 12:54:47"
        },
        "api-admin": {
            "status": "false",
            "when": "19-01-2016 12:54:47"
        },
        "myweb": {
            "status": "false",
            "when": "19-01-2016 12:54:47"
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

脚本:

JQ=$(which jq)
CACHE='cache.json'
PROJECT=("api-client" "api-admin" "myweb")
for PROJECT in ${PROJECTS[*]}; do
    if [[ $(${JQ} -r ".projects.\"${PROJECT}\"" ${CACHE}) != null ]]; then
        if [[ $(${JQ} -r ".projects.\"${PROJECT}\".status" ${CACHE}) == true ]]; then
            local PROJECTDATE=$(${JQ} -r ".projects.\"${PROJECT}\".when" ${CACHE})
            local STATUS="${COLOR_GREEN}Installed${CLEAR} on ${COLOR_YELLOW}${PROJECTDATE}${CLEAR}"
        else
            local STATUS="${COLOR_RED}Not installed${CLEAR}"
        fi
        echo -e "${CLEAR}    - ${COLOR_CYAN}${PROJECT}${CLEAR} => ${STATUS}"
    fi
done
Run Code Online (Sandbox Code Playgroud)

错误:错误:语法错误,意外的QQSTRING_START,期望IDENT .projects。“ api-client” ^ 1编译错误错误:语法错误,意外的QQSTRING_START,预期IDENT .projects。“ api-client” .status ^ 1编译错误-api -client =>未安装

有人可以帮我调试脚本吗?

小智 5

首先,.foo.bar只是的简写语法.["foo"]["bar"]。将后者用于非字母数字值,例如api-client

其次,永远不要通过将shell变量插入到其中来组成jq脚本。而是使用--arg将值传递给它们。也就是说,不要这样做:

${JQ} -r ".projects.\"${PROJECT}\"" ${CACHE}
Run Code Online (Sandbox Code Playgroud)

您可能应该这样做:

${JQ} --arg project "$PROJECT" -r '.projects[$project]' ${CACHE}
Run Code Online (Sandbox Code Playgroud)

注意jq程序周围的单引号:$project是jq变量的语法,例如在Perl或PHP中;它不会被外壳插补。始终在jq程序周围使用单引号。

第三,可以使用,-e使真实值的状态码为0。代替这个:

if [[ $(${JQ} -r ".projects.\"${PROJECT}\"" ${CACHE}) != null ]]; then
Run Code Online (Sandbox Code Playgroud)

您可以这样做:

if ${JQ} --arg project "$PROJECT" -e -r '.projects[$project]' ${CACHE}; then
Run Code Online (Sandbox Code Playgroud)

同样,您可以用相同的方式将比较结果删除为true。