验证 jq 和 bash 是否存在 json 字段?
verify that a json field exists with jq and bash?
我有一个脚本使用 jq 来解析 json 字符串 MESSAGE
(从另一个应用程序读取)。同时 json 发生了变化,一个字段被拆分为 2 个字段:file_path
现在拆分为 folder
和 file
。脚本正在读取 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/fl
或 null/fl
。所以我想创建一个 if 来验证文件夹字段是否存在,但似乎我做错了,无法找出问题所在。输出是
bash: [: missing `]'
jq: ]: No such file or directory
null/fl
我会在 jq
过滤器中完成所有操作:
echo "$MESSAGE" | jq -r '[ .folder, .file ] | join("/")'
如果你想用 bash 来做(或者想在 bash 中学习如何做这类事情),两点:
- Shell 变量在使用时几乎总是应该被引用(即
"$MESSAGE"
而不是 $MESSAGE
)。如果 JSON 中的某个字符串包含 shell 元字符(例如 *
)而您忘记这样做,您将 运行 陷入有趣的问题;该字符串将受到 shell 扩展(并且 *
将扩展为当前工作目录中的文件列表)。
- A shell
if
接受命令作为条件,并根据该命令的退出状态决定分支位置(如果退出状态为 0
,则为真,否则为假)。您尝试使用的 [
只是一个命令([=20= 的别名],请参阅 man test
)并且没有任何特殊意义。
因此,目标是构造一个命令,如果 JSON 对象具有 folder
属性,则该命令以 0
退出,否则为非零。 jq
有一个 -e
选项,如果最后的输出值不是 false
或 null
并且非零,则它会变成 return 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
(它被忽略),这样我们就不会在控制台上看到它。
我有一个脚本使用 jq 来解析 json 字符串 MESSAGE
(从另一个应用程序读取)。同时 json 发生了变化,一个字段被拆分为 2 个字段:file_path
现在拆分为 folder
和 file
。脚本正在读取 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/fl
或 null/fl
。所以我想创建一个 if 来验证文件夹字段是否存在,但似乎我做错了,无法找出问题所在。输出是
bash: [: missing `]'
jq: ]: No such file or directory
null/fl
我会在 jq
过滤器中完成所有操作:
echo "$MESSAGE" | jq -r '[ .folder, .file ] | join("/")'
如果你想用 bash 来做(或者想在 bash 中学习如何做这类事情),两点:
- Shell 变量在使用时几乎总是应该被引用(即
"$MESSAGE"
而不是$MESSAGE
)。如果 JSON 中的某个字符串包含 shell 元字符(例如*
)而您忘记这样做,您将 运行 陷入有趣的问题;该字符串将受到 shell 扩展(并且*
将扩展为当前工作目录中的文件列表)。 - A shell
if
接受命令作为条件,并根据该命令的退出状态决定分支位置(如果退出状态为0
,则为真,否则为假)。您尝试使用的[
只是一个命令([=20= 的别名],请参阅man test
)并且没有任何特殊意义。
因此,目标是构造一个命令,如果 JSON 对象具有 folder
属性,则该命令以 0
退出,否则为非零。 jq
有一个 -e
选项,如果最后的输出值不是 false
或 null
并且非零,则它会变成 return 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
(它被忽略),这样我们就不会在控制台上看到它。