如何在shell脚本中解析JSON?

如何在shell脚本中解析JSON?,json,bash,shell,sh,jq,Json,Bash,Shell,Sh,Jq,我运行curl命令$(curl-I-o---silent-xget--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:

我运行curl命令
$(curl-I-o---silent-xget--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”分配给两个不同的变量,在这里我可以打印status和details。此外,如果状态等于error,则脚本应退出。为了完成这项任务,我正在做以下工作-

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')

您可以使用如下构造:

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

首先阅读status1 details1<,停止使用
-i
参数
curl
。这样就不需要
awk
(或者事后对头进行任何其他修剪)

第二:

{
  IFS= read -r -d '' status1
  IFS= read -r -d '' details1
} < <(jq -r '.status + "\u0000" + .details + "\u0000"' <<<"$response")
{
IFS=读取-r-d''状态1
IFS=读取-r-d“”详细信息1

}<正如Benjamin已经建议的,只检索json是一种更好的方法。Poshi的解决方案是固体的

但是,如果您正在寻找最紧凑的方法来实现这一点,那么不需要将响应保存为变量,如果您唯一要做的就是一次性从中提取其他变量。只需将管道直接卷曲成:

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


然后您将得到您的值。

您的
curl
命令是什么样子的?如果您要以任何方式丢弃标题m,您可以首先将它们保留在
$response
之外。如果您丢弃
-i
,您将无法获得标题。如果您希望允许使用任意字符串而不是依赖空格,您可以根据使用nul字节
curl "whatever" | jq -r '[.status, .details] |join("\t")'