如果 json 为空,jq 将 null 作为字符串返回

Tol*_*urt 8 bash jq

我正在运行这个命令从 json 中获取一个值;

addr=$(./xuez-cli getnetworkinfo | jq -r '.localaddresses[0].address')

它工作得很好。

但是,如果这部分为.localaddresses[0].address空或什至不存在,jq 将addr变量设置为null这样;addr=null

我想检查 json 是否为空/空并运行其他一些命令而不是将其解析为null字符串。

我找不到解决此问题的方法。我怎样才能做到这一点?

小智 31

我发现对 shell 脚本有用的东西是:

jq '.foo // empty'
Run Code Online (Sandbox Code Playgroud)

如果成功则返回匹配,如果不成功则返回空字符串。所以在 bash 中我使用:

addr=$(./xuez-cli getnetworkinfo | jq -r '.localaddresses[0].address // empty')

if [[ ! -z "$addr" ]]; then
    # do something
fi
Run Code Online (Sandbox Code Playgroud)

参考:https : //github.com/stedolan/jq/issues/354#issuecomment-43147898 https://unix.stackexchange.com/questions/451479/jq-print-for-null-values

  • 我认为这应该是适当的正确答案,因为它更好地反映了空字符串的问题,所以请@Tolgahan Bozkurt 批准这个答案作为正确的答案! (2认同)

Cha*_*ffy 6

First, a note: There's nothing inherently wrong with addr=null; you can just test for it:

if [[ $addr = null ]]; then ...code here...; fi
Run Code Online (Sandbox Code Playgroud)

The rest of this answer pretends the above were untrue. :)


There are two practices that are notable as improving ease of error handling for this case:

  • Using set -o pipefail will detect whether any part -- not just the last component -- of a shell pipeline fails.
  • Using jq -e will cause jq's exit status to reflect whether it returned content that was either false or null.

Thus:

set -o pipefail
if addr=$(./xuez-cli getnetworkinfo | jq -er '.localaddresses[0].address'); then
  : "address retrieved successfully; this message is not logged unless set -x is active"
else
  echo "Running other logic here"
fi
Run Code Online (Sandbox Code Playgroud)

...goes to Running other logic here if either jq fails (and -e specifies that false and null shall be treated as failures), or if xuez-cli reports an unsuccessful exit status.