将JSON对象的成员解析为Bash变量 [英] Parse JSON object's members into Bash variables

查看:97
本文介绍了将JSON对象的成员解析为Bash变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设,我已经安装了此软件包 jq 。所以我运行了这个命令

Let's assume, I have this package jq installed. So I ran this command

curl -s ipinfo.io/33.62.137.111

并获得此结果

{
  "ip": "33.62.137.111",
  "city": "Columbus",
  "region": "Ohio",
  "country": "US",
  "loc": "39.9690,-83.0114",
  "postal": "43218",
  "timezone": "America/New_York",
  "readme": "https://ipinfo.io/missingauth"
}

我知道通过执行此操作,我可以得到城市

I know I can get city by doing this

curl -s ipinfo.io/33.62.137.111 | jq -r '.city' 

我知道我可以得到地区

I know I can get region by doing this

curl -s ipinfo.io/33.62.137.111 | jq -r '. region' 

我正在尝试卷曲7次以创建7个变量。

I'm trying to curl 7 times to create 7 variables.

有没有一种方法可以基于第一个curl响应创建多个变量?

Is there a way to create multiple variables based on the first curl response?

推荐答案

它在Bash 4+中使用关联数组很容易:

It is easy with Bash 4+ using an associative array:

#!/usr/bin/env bash

# Map the JSON response into an associative array
declare -A "assoc_array=($(
  curl -s ipinfo.io/33.62.137.111 |
    jq -r 'to_entries[] | "[\(.key | @sh)]=\(.value | @sh)"'
))"
IFS=, read -r assoc_array[lat] assoc_array[long] <<<"${assoc_array[loc]}"

echo "Here is how assoc_array was declared/created"
echo
typeset -p assoc_array
echo
echo

# Display the content of the associative array
echo "Here is a breakdown of all entries in the assoc_array:"
echo
for k in "${!assoc_array[@]}"; do
  printf '%q = %q\n' "$k" "${assoc_array[$k]}"
done

示例输出:

Here is how assoc_array was declared/created

declare -A assoc_array=([country]="US" [region]="Ohio" [city]="Columbus" [timezone]="America/New_York" [ip]="33.62.137.111" [lat]="39.9690" [readme]="https://ipinfo.io/missingauth" [long]="-83.0114" [loc]="39.9690,-83.0114" [postal]="43218" )


Here is a breakdown of all entries in the assoc_array:

country = US
region = Ohio
city = Columbus
timezone = America/New_York
ip = 33.62.137.111
lat = 39.9690
readme = https://ipinfo.io/missingauth
long = -83.0114
loc = 39.9690\,-83.0114
postal = 43218



对于较旧的Bash,这有点棘手,但在这里



它用ASCII ETX (值 3 表示 T e x t中的E nd,并生成带有 jq 的字段流,然后读取每个变量都按可预测的顺序排列。如果JSON响应对象中缺少键,则该字段将为空。

For older Bash, it is a bit trickier but here it is

It separates values by the ASCII ETX (Value 3 for End of Text) and generates a stream of fields with jq, then read each variable into the predictable order. If a key is missing from the JSON response object, the field will be empty.

与关联数组方法相反,必须事先知道键名并在预测顺序(所有这些都由长的 jq 查询处理)。

Contrarily to the associative array method, key names have to be known beforehand and provided in a predicted order (all this is handled by the long jq query).

#!/usr/bin/env bash

IFS=$'\3' read -r ip hostname city region country lat long postal timezone readme < <(
  curl -s ipinfo.io/33.62.137.111 |
    jq -r '"\(.ip+"\u0003")\(.hostname+"\u0003")\(.city+"\u0003")\(.region+"\u0003")\(.country+"\u0003")\(.loc | split(",") |"\(.[0]+"\u0003")\(.[1]+"\u0003")")\(.postal+"\u0003")\(.timezone+"\u0003")\(.readme+"\u0003")"'
)

printf 'ip = %q\n' "$ip"
printf 'hostname = %q\n' "$hostname"
printf 'city = %q\n' "$city"
printf 'region = %q\n' "$region"
printf 'country = %q\n' "$country"
printf 'latitude = %q\n' "$lat"
printf 'longitude = %q\n' "$long"
printf 'postal code = %q\n' "$postal"
printf 'timezone = %q\n' "$timezone"
printf 'readme = %q\n' "$readme"

示例输出:

ip = 33.62.137.111
hostname = ''
city = Columbus
region = Ohio
country = US
latitude = 39.9690
longitude = -83.0114
postal code = 43218
timezone = America/New_York
readme = https://ipinfo.io/missingauth

这篇关于将JSON对象的成员解析为Bash变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆