linux 如何在shell脚本中解析json响应?

8oomwypt  于 2023-04-20  发布在  Linux
关注(0)|答案(5)|浏览(261)

我正在使用bash shell脚本。我需要使用shell脚本执行URL,然后解析来自它的JSON数据。
这是我的URL -http://localhost:8080/test_beat,我可以在点击URL后得到的响应将来自这两个-

{"error": "error_message"}
{"success": "success_message"}

下面是我的shell脚本,它使用wget执行URL。

#!/bin/bash

DATA=$(wget -O - -q -t 1 http://localhost:8080/test_beat)
#grep $DATA for error and success key

现在我不知道如何解析$DATA中的json响应,看看key是success还是error。如果key是success,那么我将打印一条消息“success”并打印$DATA value,并以零状态码退出shell脚本,但如果key是error,那么我将打印“error”并打印$DATA value,并以非零状态码退出shell脚本。
如何解析json响应并在shell脚本中从中提取密钥?
我不想安装任何库来做这件事,因为我的JSON响应是固定的,它将始终与上面所示的相同,所以任何更简单的方法都可以。

更新:-

下面是我最后的shell脚本--

#!/bin/bash

DATA=$(wget -O - -q -t 1 http://localhost:8080/tester)
echo $DATA
#grep $DATA for error and success key
IFS=\" read __ KEY __ MESSAGE __ <<< "$DATA"
case "$KEY" in
success)
    exit 0
    ;;
error)
    exit 1
    ;;
esac

这看起来对吗?

2sbarzqh

2sbarzqh1#

如果你打算从shell中使用任何更复杂的json,并且你可以安装其他软件,jq将是你的朋友。
因此,例如,如果您只想提取错误消息(如果存在),那么您可以这样做:

$ echo '{"error": "Some Error"}' | jq ".error"
"Some Error"

如果你在成功案例中尝试这个,它会做到:

$echo '{"success": "Yay"}' | jq ".error"
null

该工具的主要优点很简单,它完全理解JSON。因此,无需担心角落情况和诸如此类的问题。

nvbavucw

nvbavucw2#

#!/bin/bash
IFS= read -d '' DATA < temp.txt  ## Imitates your DATA=$(wget ...). Just replace it.
while IFS=\" read -ra LINE; do
    case "${LINE[1]}" in
    error)
        # ERROR_MSG=${LINE[3]}
        printf -v ERROR_MSG '%b' "${LINE[3]}"
        ;;
    success)
        # SUCCESS_MSG=${LINE[3]}
        printf -v SUCCESS_MSG '%b' "${LINE[3]}"
        ;;
    esac
done <<< "$DATA"
echo "$ERROR_MSG|$SUCCESS_MSG"  ## Shows: error_message|success_message

*****%b扩展相应参数中的反斜杠转义序列。

更新,因为我没有真正得到的问题在第一。它应该简单地是:

IFS=\" read __ KEY __ MESSAGE __ <<< "$DATA"
[[ $KEY == success ]]  ## Gives $? = 0 if true or else 1 if false.

你可以进一步研究它:

case "$KEY" in
success)
    echo "Success message: $MESSAGE"
    exit 0
    ;;
error)
    echo "Error message: $MESSAGE"
    exit 1
    ;;
esac

当然,类似的明显的测试可以用它来完成:

if [[ $KEY == success ]]; then
    echo "It was successful."
else
    echo "It wasn't."
fi

从你的最后一条评论,它可以简单地做

IFS=\" read __ KEY __ MESSAGE __ <<< "$DATA"
echo "$DATA"  ## Your really need to show $DATA and not $MESSAGE right?
[[ $KEY == success ]]
exit  ## Exits with code based from current $?. Not necessary if you're on the last line of the script.
ppcbkaq5

ppcbkaq53#

你可能已经安装了python,它在标准库中有json解析。Python不是shell脚本中一行程序的好语言,但这里有一种使用它的方法:

#!/bin/bash

DATA=$(wget -O - -q -t 1 http://localhost:8080/test_beat)

if python -c '
import json, sys
exit(1 if "error" in json.loads(sys.stdin.read()) else 0)' <<<"$DATA"
then
  echo "SUCCESS: $DATA"
else
  echo "ERROR: $DATA"
  exit 1
fi
to94eoyn

to94eoyn4#

给出:

  • 你不想使用JSON库。
  • 并且你解析的响应很简单,你唯一关心的是子字符串"success"的存在,我建议如下简化
#!/bin/bash

wget -O - -q -t 1 http://localhost:8080/tester | grep -F -q '"success"'
exit $?
  • -F告诉grep搜索一个固定的(文字)字符串。
  • -q告诉grep不产生任何输出,而是通过它的 * 退出代码 * 反映是否找到匹配。
  • exit $?只是使用grep的退出代码退出($?是一个特殊的变量,它反映了最近执行的命令的退出代码)。

请注意,如果您只关心 * wget的输出是否包含"success",则上述管道将执行此操作-无需在aux.变量中捕获wget的输出。

mpbci0fu

mpbci0fu5#

纯Bash 3.2+,无依赖(如jq、python、grep等):

source <(curl -s -L -o- https://github.com/lirik90/bashJsonParser/raw/master/jsonParser.sh)
JSON='{"error": "error_message"}'
JSON=$(minifyJson "$JSON")
echo "Message is: $(parseJson "$JSON" error)"

Try it

相关问题