【问题标题】:Parse JSON object's members into Bash variables将 JSON 对象的成员解析为 Bash 变量
【发布时间】:2020-04-03 01:17:19
【问题描述】:

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

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"
}

我知道我可以通过这样做获得city

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

我知道我可以通过这样做获得region

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

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

有没有办法根据第一个 curl 响应创建多个变量?

【问题讨论】:

  • jq -r '.[]' 也许
  • @cyber8200 您需要包含jq 的答案吗?如果是,请添加标签jq

标签: json bash shell curl


【解决方案1】:

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

#!/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 分隔值(End of Tex 的值 3 t) 并生成带有jq 的字段流,然后将每个变量读入可预测的顺序。如果 JSON 响应对象中缺少键,则该字段将为空。

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

#!/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

【讨论】:

    【解决方案2】:

    您可能对 感兴趣。您的用例不需要curljq,甚至不需要 Bash 脚本。

    检索 JSON:

    xidel -s --user-agent=curl "https://ipinfo.io/33.62.137.111" -e '$json'
    {
      "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"
    }
    

    解析 JSON,使用 Xidel 的 eval() 函数为每个键值对自动创建(内部)变量,并使用 Bash 内置的 eval 命令将它们转换为 shell 变量:

    xidel -s --user-agent=curl "https://ipinfo.io/33.62.137.111" -e '$json() ! eval(x"{.}:=$json/{.}")[0]' --output-format=bash
    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'
    result=
    
    eval "$(xidel -s --user-agent=curl "https://ipinfo.io/33.62.137.111" -e '$json() ! eval(x"{.}:=$json/{.}")[0]' --output-format=bash)"
    
    printf '%s\n' $ip $city $region $country $loc $postal $timezone $readme
    33.62.137.111
    Columbus
    Ohio
    US
    39.9690,-83.0114
    43218
    America/New_York
    https://ipinfo.io/missingauth
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多