如何使用 jq 获得输出,就像它给出单词或字符串进入的整行一样

如何使用 jq 获得输出,就像它给出单词或字符串进入的整行一样

我的问题有点相似,但仍然允许我详细说明。我一直在访问一个名为 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 中使用j2inj1会导致回复中的 JSON 文档更小。

相关内容