【问题标题】:verify that a json field exists with jq and bash?验证 jq 和 bash 是否存在 json 字段?
【发布时间】:2015-04-10 13:47:19
【问题描述】:

我有一个使用 jq 解析 json 字符串 MESSAGE 的脚本(从另一个应用程序读取)。同时,json 发生了变化,一个字段被拆分为 2 个字段:file_path 现在拆分为 folderfile。该脚本正在读取file_path,现在folder 可能不存在,因此为了创建文件的路径,我必须验证该字段是否存在。我在互联网上搜索了一段时间,并设法做到:

echo $(echo $MESSAGE | jq .folder -r)$'/'$(echo $MESSAGE | jq .file -r)

if [ $MESSAGE | jq 'has(".folder")' -r  ]
then
        echo $(echo $MESSAGE | jq .folder -r)$'/'$(echo $MESSAGE | jq .file -r)
else
        echo $(echo $MESSAGE | jq .file -r)
fi

在哪里MESSAGE='{"folder":"FLDR","file":"fl"}'MESSAGE='{"file":"fl"}'

如果文件夹字段不存在,第一行打印FLDR/flnull/fl。所以我想创建一个 if 来验证文件夹字段是否存在,但似乎我做错了,无法找出问题所在。输出是

bash: [: missing `]'
jq: ]: No such file or directory
null/fl

【问题讨论】:

    标签: json bash jq


    【解决方案1】:

    我会在 jq 过滤器中完成所有事情:

    echo "$MESSAGE" | jq -r '[ .folder, .file ] | join("/")'
    

    如果你想用 bash 来做(或学习如何用 bash 做这类事情),两点:

    • Shell 变量在使用时几乎总是应该被引用(即"$MESSAGE" 而不是$MESSAGE)。如果您的 JSON 中的某个字符串曾经包含 shell 元字符(例如 *)而您忘记了这样做,您将会遇到有趣的问题;该字符串将受到 shell 扩展(并且 * 将扩展为当前工作目录中的文件列表)。
    • shell if 接受命令作为条件,并根据该命令的退出状态决定分支到哪里(如果退出状态为 0,则为 true,否则为 false)。您尝试使用的 [ 只是一个命令(test 的别名,请参阅 man test),并没有任何特殊之处。

    因此,如果 JSON 对象具有 folder 属性,则目标是构造一个以 0 退出的命令,否则为非零。 jq 有一个 -e 选项,如果最后一个输出值不是 falsenull 则返回 0 ,否则返回非零,所以我们可以写

    if echo "$MESSAGE" | jq -e 'has("folder")' > /dev/null; then
        echo "$MESSAGE" | jq -r '.folder + "/" + .file'
    else
        echo "$MESSAGE" | jq -r .file
    fi
    

    > /dev/null 位将输出从jq 重定向到/dev/null(它被忽略),因此我们在控制台上看不到它。

    【讨论】:

    • 我应该安装一些东西吗,因为 -e 无法识别?
    • 你使用的是什么版本的jq
    • -e 显然是在 1.4 中引入的。如果您有较旧的jq 版本,则可以改用if [ "$(echo "$MESSAGE" | jq 'has("folder")')" == "true" ]; then$() 替换为其中的命令输出;这是一种流程替代形式。不过,再一次,我会在 jq 过滤器中完成整个操作,并废弃 if 的外壳。
    • 如果我有一个“subjson”,比如MESSAGE='{"field":{"folder":"F", "file":"f"}}',我该怎么做?其实has是怎么变化的?
    • jq '.field | has("folder")'。或者jq -r '.field | [ .folder, .file ] | join("/")',一口气搞定。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-01-02
    • 2021-09-29
    • 2015-02-20
    • 1970-01-01
    • 2021-12-26
    • 2015-09-23
    • 1970-01-01
    相关资源
    最近更新 更多