json - bash JSON with jq - 如何检查空的 JSON 成员?

标签 json bash if-statement jq

我想根据错误消息 JSON 字段为空或非空来检测错误。我正在使用 jq 来切出成员,但是在我的 bash“if”中评估它时遇到了很大的麻烦。

我有一个由我的变量 $input 引用的 json 文件,它确实有一个 errMsg 成员,但它是一个空字符串(请注意我的 CLI 提示符是 ~$):

~$ echo $(jq "." $input)
{ "projectCode": "145", "fullCode": "1", "errMsg": "" }

在这种情况下检索 errMsg 字段会正确地产生一个空字符串:

~$ err=$(jq ".errMsg" $input)
~$ echo $err
""

问题:测试该变量似乎是不可能的:

~$ if [ $err = "" ]; then echo EMPTY; else echo CONTENT; fi 
CONTENT

我期望 EMPTY 因为 $err 刚刚显示“”。检查其他方式:

~$ if [ $err != "" ]; then echo EMPTY; else echo CONTENT; fi
EMPTY 

所以 $err 显然不是 "",即使 echo $err 产生 ""? 怎么可能 ?我在这里缺少什么 bash 功能?

无论如何,让我们尝试使用非空 json(在更改 $input 内容之后):

~$ echo $(jq "." $input)
{ "projectCode": "145", "fullCode": "1", "errMsg": "not empty" }
~$ echo $err
"not empty"

~$ if [ $err != "" ]; then echo EMPTY; else echo CONTENT; fi
bash: syntax error near unexpected token `then'

好的,然后像这样屏蔽:

~$ if [ "$err" != "" ]; then echo EMPTY; else echo CONTENT; fi
bash: syntax error near unexpected token `then'

我猜它在“not”之后找到了第二个标记并且不喜欢它。 经过大量研究,我发现这个似乎有效的真正不可读的解决方案:

~$ val=$(sed "s/^\(\"\)\(.*\)\1\$/\2/g" <<<"$err" | sed -e 's/\s.*$//')
~$ if [ "$val" = "" ]; then echo "NO ERROR"; else echo "ERROR"; fi
NO ERROR

它也适用于非空的 errMsg 成员。拜托,必须有一个简单而优雅的解决方案。

最佳答案

让我们从头开始讨论这个问题,以便您了解正在发生的事情。

~$ err=$(jq ".errMsg" $input)
~$ echo $err
""

此输出表明err包含""(它也可能在""前后有一些空格)。 这与空字符串不同。 它实际上是两个双引号字符。

~$ if [ $err = "" ]; then echo EMPTY; else echo CONTENT; fi 
CONTENT

I excpected the EMPTY as $err just showed "".

如前所述,$err 不是空的,它包含两个双引号。 另一方面,在 Bash 语句 [ ... = ""] 中,"" 确实意味着一个空值。

Bash 语句 [ $err = ""] 有问题, 因为如果 $err 的值为空会导致语法错误, 或者它是否包含空格(假设您尚未自定义 IFS)。

编写此语句的正确方法是将 $err 括在双引号中:

if [ "$err" = "" ]; then echo EMPTY; else echo CONTENT; fi

第一个命令中的 $input 变量也是如此,它应该写成:

err=$(jq ".errMsg" "$input")

如果你想检查对象中的空 .errMsg 值, 您至少有两个选择。

选项 1:检查值是否为 ""

if [ "$err" = '""' ]; then echo EMPTY; else echo CONTENT; fi

选项 2:使 jq 以原始模式输出,因此它不包括围绕字符串值的封闭双引号。

err=$(jq -r ".errMsg" "$input")
if [ "$err" = "" ]; then echo EMPTY; else echo CONTENT; fi

我推荐后一种选择,这样 err 的值就是真正的值。封闭的双引号似乎只是您的目的的噪音。

关于json - bash JSON with jq - 如何检查空的 JSON 成员?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46652354/

相关文章:

javascript - 直接访问 JSON 子对象的更好方法

asp.net - 不使用 FormsAuthentication.RedirectFromLoginPage 时如何将 Request.IsAuthenticated 设置为 true?

java - 如何在 Sublime Text 3 中自动导入 java 库?

linux - 在 If 语句中使用 grep 获取所有项目,忽略空格

javascript - 如何重新创建 json 对象

bash - 使用 `tail -f` 截断文件时清屏

linux - linux下如何使组内文件的权限与属主相同?

javascript - if 语句发生变化

excel - 如何将 1 添加到 Excel 中最近的重复行?

php - if else 重定向到另一个页面的语句