How to parse json response in the shell script?

放肆的年华 提交于 2021-02-04 04:56:43

问题


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.

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 -

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

Below is my shell script which executes the URL using wget.

#!/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.

How can I parse json response and extract the key from it in shell script?

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.

Update:-

Below is my final shell script -

#!/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?


回答1:


#!/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.


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.



回答2:


If you are going to be using any more complicated json from the shell and you can install additional software, jq is going to be your friend.

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.




回答3:


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:

#!/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



回答4:


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:
#!/bin/bash

wget -O - -q -t 1 http://localhost:8080/tester | grep -F -q '"success"'
exit $?
  • -F tells grep to search for a fixed (literal) string.
  • -q tells grep to produce no output and instead only reflect via its exit code whether a match was found or not.
  • exit $? simply exits with grep's exit code ($? is a special variable that reflects the most recently executed command's exit code).

Note that if you all you care about is whether wget's output contains "success", the above pipeline will do - no need to capture wget's output in an aux. variable.



来源:https://stackoverflow.com/questions/24644520/how-to-parse-json-response-in-the-shell-script

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!