将JSON对象的成员解析为Bash变量 [英] Parse JSON object's members into Bash variables
问题描述
假设,我已经安装了此软件包 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屋!