[英]How to parse JSON in shell script?
I run the curl command $(curl -i -o - --silent -X GET --cert "${CERT}" --key "${KEY}" "$some_url")
and save the response in the variable response. 我运行curl命令$(curl -i -o - --silent -X GET --cert "${CERT}" --key "${KEY}" "$some_url")
并将响应保存在变量响应中。 ${response} is as shown below $ {response}如下所示
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Content-Length: 34
Connection: keep-alive
Keep-Alive: timeout=5
X-XSS-Protection: 1;
{"status":"running","details":"0"}
I want to parse the JSON {"status":"running","details":"0"}
and assign 'running' and 'details' to two different variables where I can print status and details both. 我想解析JSON {"status":"running","details":"0"}
并将'running'和'details'分配给两个不同的变量,我可以在这两个变量中打印状态和详细信息。 Also if the status is equal to error, the script should exit. 此外,如果状态等于错误,则脚本应退出。 I am doing the following to achieve the task - 我正在做以下任务来完成任务 -
status1=$(echo "${response}" | awk '/^{.*}$/' | jq -r '.status')
details1=$(echo "${response}" | awk '/^{.*}$/' | jq -r '.details')
echo "Status: ${status1}"
echo "Details: ${details1}"
if [[ $status1 == 'error' ]]; then
exit 1
fi
Instead of parsing the JSON twice, I want to do it only once. 我想要只做一次,而不是两次解析JSON。 Hence I want to combine the following lines but still assign the status and details to two separate variables - 因此,我想结合以下几行,但仍然将状态和细节分配给两个单独的变量 -
status1=$(echo "${response}" | awk '/^{.*}$/' | jq -r '.status')
details1=$(echo "${response}" | awk '/^{.*}$/' | jq -r '.details')
First, stop using the -i
argument to curl
. 首先, 停止使用-i
参数进行curl
。 That takes away the need for awk
(or any other pruning of the header after-the-fact). 这消除了对awk
的需求(或事后的任何其他头部修剪)。
Second: 第二:
{
IFS= read -r -d '' status1
IFS= read -r -d '' details1
} < <(jq -r '.status + "\u0000" + .details + "\u0000"' <<<"$response")
The advantage of using a NUL as a delimiter is that it's the sole character that can't be present in the value of a C-style string (which is how shell variables' values are stored). 使用NUL作为分隔符的优点是它是唯一的字符,不能出现在C风格字符串的值中(这是shell变量值的存储方式)。
You can use a construction like: 你可以使用如下结构:
read status1 details1 < <(jq -r '.status + " " + .details' <<< "${response}")
You use read to assign the different inputs to two variables (or an array, if you want), and use jq
to print the data you need separated by whitespace. 您可以使用read将不同的输入分配给两个变量(或数组,如果需要),并使用jq
打印您需要用空格分隔的数据。
As Benjamin already suggested, only retrieving the json is a better way to go. 正如本杰明已经建议的那样,只检索json是一种更好的方法。 Poshi's solution is solid. Poshi的解决方案很扎实。
However, if you're looking for the most compact to do this, no need to save the response as a variable if the only thing your're going to do with it is extract other variables from it on a one time basis. 但是,如果您正在寻找最紧凑的方法,那么无需将响应保存为变量,如果您要做的唯一事情就是一次性从中提取其他变量。 Just pipe curl directly into: 只需将卷曲直接卷入:
curl "whatever" | jq -r '[.status, .details] |@tsv'
or 要么
curl "whatever" | jq -r '[.status, .details] |join("\t")'
and you'll get your values fielded for you. 并且你会得到你的价值观。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.