我的问题有点相似,但仍然允许我详细说明。我一直在访问一个名为 wttr.in 的天气应用程序,从中我可以获得天气信息。这可以很容易地通过 -
$ curl wttr.in/Pune?format=4
现在我有兴趣知道气象站是否提供当前数据或陈旧数据,为此我知道了一种称为 j1 格式的格式,该格式给出了服务器上次更新天气信息的时间。
$ curl wttr.in/Pune?format=j1 | less
上面的查询给了我大量的数据,比如 -
current_condition": [
{
"FeelsLikeC": "18",
"FeelsLikeF": "65",
"cloudcover": "4",
"humidity": "42",
"localObsDateTime": "2021-11-11 12:20 AM",
"observation_time": "06:50 PM",
"precipInches": "0.0",
"precipMM": "0.0",
"pressure": "1012",
"pressureInches": "30",
"temp_C": "18",
现在如果我使用 grep 我会得到这样的输出 -
$ curl wttr.in/Pune?format=j1 | grep "localObsDateTime"
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
2 48685 2 1159 0 0 4199 0 0:00:11 --:--:-- 0:00:11 4184 "localObsDateTime": "2021-11-11 12:20 AM",
100 48685 100 48685 0 0 90830 0 --:--:-- --:--:-- --:--:-- 90661
我听说 jq 可以美化它并且变得简单,有人可以告诉我怎么做吗?另外,如果有任何其他方式来获取数据而不是curl也会很有趣。
FWIW我已经安装了ja 1.6,我的bash版本是5.1.8。
答案1
和jq
:
curl -s 'http://wttr.in/Pune?format=j1' | jq -r '.current_condition[].localObsDateTime'
输出:
2021-11-11 03:01 上午
答案2
您可以使用:
curl wttr.in/Pune?format=j1 | jq '.current_condition[].localObsDateTime'
答案3
如果您不知道密钥在 JSON 文档中的确切位置localObsDateTime
,则必须递归搜索它。您可以这样做,然后使用以下jq
表达式提取其值:
.. | select(type == "object" and has("localObsDateTime")).localObsDateTime
这本质上是说“对于文档中的每个单独的事物,如果它是一个对象并且有一个名为 的键localObsDateTime
,则提取该键的值”。
您也可以将其缩短为
.. | .localObsDateTime? // empty
其中表示“对于文档中的每个单独的事物,尝试提取localObsDateTime
值(如果存在),如果不存在或其值是null
,则什么也不给我”。
你可以这样运行:
$ curl -s 'http://wttr.in/Pune?format=j2' |
jq -r '.. | select(type == "object" and has("localObsDateTime")).localObsDateTime'
2021-11-17 12:16 AM
或者,
$ curl -s 'http://wttr.in/Pune?format=j2' |
jq -r '.. | .localObsDateTime? // empty'
2021-11-17 12:16 AM
该-r
选项jq
使实用程序返回解码的文本字符串而不是 JSON 字符串。
请注意,上面返回的值全部 localObsDateTime
键。如果您只需要其中第一个,请改用以下jq
表达式:
[ .. | select(type == "object" and has("localObsDateTime")).localObsDateTime ][0]
或者,
[ .. | .localObsDateTime? // empty ][0]
这将创建一个包含所有值的数组,然后提取第一个值。
请注意,在 URL 中使用j2
inj1
会导致回复中的 JSON 文档更小。