如何在Shell脚本中解析JSON?

时间:2018-11-27 22:01:40

标签: json bash shell sh jq

我运行curl命令$(curl -i -o - --silent -X GET --cert "${CERT}" --key "${KEY}" "$some_url")并将响应保存在变量response中。 $ {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"}

我想解析JSON {"status":"running","details":"0"}并将'running'和'details'分配给两个不同的变量,我可以在其中打印状态和详细信息。同样,如果状态等于错误,则脚本应退出。我正在执行以下任务以实现任务-

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

我不想解析JSON两次,而是只做一次。因此,我想结合以下几行,但仍将状态和详细信息分配给两个单独的变量-

status1=$(echo "${response}" | awk '/^{.*}$/' | jq -r '.status')
details1=$(echo "${response}" | awk '/^{.*}$/' | jq -r '.details')

3 个答案:

答案 0 :(得分:5)

首先,停止使用-i的{​​{1}}参数。这样就无需使用curl(或事后对标题进行其他任何修剪)。

第二:

awk

使用NUL作为分隔符的优点是,它是C样式字符串的值(存储shell变量的值的方式)中不能出现的唯一字符。

答案 1 :(得分:1)

您可以使用以下结构:

read status1 details1 < <(jq -r '.status + " " + .details' <<< "${response}")

您可以使用read将不同的输入分配给两个变量(或数组,如果需要),并使用jq打印需要用空格隔开的数据。

答案 2 :(得分:1)

如本杰明(Benjamin)所建议的那样,仅检索json是更好的方法。 Poshi的解决方案很可靠。

但是,如果您正在寻找最紧凑的方法来执行此操作,那么如果您唯一要做的就是一次性从中提取其他变量,则无需将响应另存为变量。只需将卷发直接插入:

curl "whatever" | jq -r '[.status, .details] |@tsv' 

curl "whatever" | jq -r '[.status, .details] |join("\t")'

,您将为您获得自己的价值。