验证jq和bash存在json字段?

时间:2015-04-10 13:47:19

标签: json bash jq

我有一个脚本使用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。所以我想创建一个如果验证文件夹字段是否存在,但似乎我做错了,无法弄清楚是什么问题。输出是

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

1 个答案:

答案 0 :(得分:8)

我会在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对象具有0属性,则以folder退出,否则为非零。 jq有一个-e选项,如果最后一个输出值不是0false,则返回null,否则返回非零,所以我们可以写

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(忽略它),以便我们在控制台上看不到它。