bash 如何在shell脚本中解析json响应?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24644520/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to parse json response in the shell script?
提问by john
I am working with bash shell script. I need to execute an URL using shell script and then parse the json data coming from it.
我正在使用 bash shell 脚本。我需要使用 shell 脚本执行一个 URL,然后解析来自它的 json 数据。
This is my URL - http://localhost:8080/test_beat
and the responses I can get after hitting the URL will be from either these two -
这是我的 URL -http://localhost:8080/test_beat
在点击 URL 后我可以获得的响应将来自这两个 -
{"error": "error_message"}
{"success": "success_message"}
Below is my shell script which executes the URL using wget.
下面是我的 shell 脚本,它使用 wget 执行 URL。
#!/bin/bash
DATA=$(wget -O - -q -t 1 http://localhost:8080/test_beat)
#grep $DATA for error and success key
Now I am not sure how to parse json response in $DATA and see whether the key is success or error. If the key is success, then I will print a message "success" and print $DATA value and exit out of the shell script with zero status code but if the key is error, then I will print "error" and print $DATA value and exit out of the shell script with non zero status code.
现在我不确定如何解析 $DATA 中的 json 响应并查看关键是成功还是错误。如果密钥成功,那么我将打印一条消息“成功”并打印 $DATA 值并以零状态代码退出 shell 脚本,但如果密钥是错误的,那么我将打印“错误”并打印 $DATA 值并以非零状态代码退出 shell 脚本。
How can I parse json response and extract the key from it in shell script?
如何解析 json 响应并在 shell 脚本中从中提取密钥?
I don't want to install any library to do this since my JSON response is fixed and it will always be same as shown above so any simpler way is fine.
我不想安装任何库来执行此操作,因为我的 JSON 响应是固定的,并且它始终与上面显示的相同,因此任何更简单的方法都可以。
Update:-
更新:-
Below is my final shell script -
下面是我的最终 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
Does this looks right?
这看起来对吗?
采纳答案by konsolebox
#!/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
expands backslash escape sequences in the corresponding argument.
*%b
在相应的参数中扩展反斜杠转义序列。
Update as I didn't really get the question at first. It should simply be:
更新,因为我一开始并没有真正明白这个问题。它应该只是:
IFS=\" read __ KEY __ MESSAGE __ <<< "$DATA"
[[ $KEY == success ]] ## Gives $? = 0 if true or else 1 if false.
And you can examine it further:
您可以进一步检查它:
case "$KEY" in
success)
echo "Success message: $MESSAGE"
exit 0
;;
error)
echo "Error message: $MESSAGE"
exit 1
;;
esac
Of course similar obvious tests can be done with it:
当然可以用它做类似的明显测试:
if [[ $KEY == success ]]; then
echo "It was successful."
else
echo "It wasn't."
fi
From your last comment it can be simply done as
从你的最后一条评论,它可以简单地做为
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.
回答by Josh Berry
If you are going to be using any more complicated json from the shell and you can install additional software, jqis going to be your friend.
如果您打算从 shell 使用任何更复杂的 json 并且您可以安装其他软件,jq将成为您的朋友。
So, for example, if you want to just extract the error message if present, then you can do this:
因此,例如,如果您只想提取错误消息(如果存在),则可以执行以下操作:
$ echo '{"error": "Some Error"}' | jq ".error"
"Some Error"
If you try this on the success case, it will do:
如果您在成功案例中尝试此操作,它将执行以下操作:
$echo '{"success": "Yay"}' | jq ".error"
null
The main advantage of the tool is simply that it fully understands json. So, no need for concern over corner cases and whatnot.
该工具的主要优点很简单,它完全理解 json。因此,无需担心极端情况等。
回答by Pontus
You probably already have python installed, which has json parsing in the standard library. Python is not a great language for one-liners in shell scripts, but here is one way to use it:
你可能已经安装了 python,它在标准库中有 json 解析。对于 shell 脚本中的单行来说,Python 不是一种很好的语言,但这里有一种使用它的方法:
#!/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
回答by mklement0
Given:
鉴于:
- that you don't want to use JSON libraries.
- and that the response you're parsing is simple and the only thing you care about is the presence of substring
"success"
, I suggest the following simplification:
- 您不想使用 JSON 库。
- 并且您解析的响应很简单,您唯一关心的是 substring 的存在
"success"
,我建议进行以下简化:
#!/bin/bash
wget -O - -q -t 1 http://localhost:8080/tester | grep -F -q '"success"'
exit $?
-F
tellsgrep
to search for a fixed (literal) string.-q
tellsgrep
to produce no output and instead only reflect via its exit codewhether a match was found or not.exit $?
simply exits withgrep
's exit code ($?
is a special variable that reflects the most recently executed command's exit code).
-F
告诉grep
搜索固定(文字)字符串。-q
告诉grep
不产生任何输出,而是仅通过其退出代码反映是否找到匹配项。exit $?
简单地使用grep
的退出代码退出($?
是一个特殊变量,它反映了最近执行的命令的退出代码)。
Note that if you all you care about is whetherwget
's output contains "success"
, the above pipeline will do - no need to capture wget
's output in an aux. variable.
请注意,如果您只关心的输出是否wget
包含"success"
,则上述管道将执行 - 无需wget
在 aux 中捕获的输出。多变的。