【问题标题】:How to get just current average temperature from wttr.in curl result with bash?如何使用 bash 从 wttr.in curl 结果中获取当前平均温度?
【发布时间】:2017-07-09 02:44:01
【问题描述】:

wttr.in 可以通过 curl wttr.in 为您提供天气:

curl wttr.in/Amsterdam

我返回了一个大数据列表,我想将其用作 tmux 段,因此我将其范围缩小到仅第一次提及温度(即当前温度):

curl wttr.in/Amsterdam | grep -m 1 °C

有时会返回一个范围:

_ /"".-.     4 – 7 °C

有时是单一温度:

_ /"".-.     13 °C

所以它前面还有一些垃圾,它有时会返回一个范围而不是单个温度。有谁知道我如何缩小范围以始终返回单个温度(如果有两个值则为平均值)并且没有前面的文本?

【问题讨论】:

  • 只是删除所有字符直到第一个数字已经是一个巨大的改进顺便说一句。我尝试使用 cut 进行操作,但无法正常工作。

标签: bash curl grep tmux


【解决方案1】:

wttr.in 现在支持自定义格式的one-line output,所以这个

curl wttr.in/Amsterdam?format=%t

只返回温度,据我所知,它返回一个值而不是一个范围。


以前版本的答案

基于我们必须自己修改响应的假设

这样做的主要困难是服务返回终端转义码,这使得处理变得混乱。这是你真正得到的:

$ curl -s wttr.in/Amsterdam | grep -m 1 '°.' | cat -A
 ^[[38;5;226m _ /""^[[38;5;250m.-.    ^[[0m ^[[38;5;048m5^[[0m M-bM-^@M-^S ^[[38;5;046m8^[[0m M-BM-0C^[[0m       $

呈现如下:

因此,我们不能只提取从第一个数字开始的所有内容,因为由于转义序列,这将包括几乎整行。

幸运的是,我们可以告诉 wttr.in 不要使用 T 查询字符串参数向我们发送颜色转义(提示 keheliya 指出这一点):

$ curl -s wttr.in/Amsterdam?T | grep -m 1 '°.' | cat -A
  _ /"".-.     5-8 M-BM-0C         $

现在我们可以使用grep -o(仅保留匹配项)从遇到的第一个数字中提取所有内容。这还考虑到负温度可能会出现负号:

curl -s wttr.in/Amsterdam?T | grep -m 1 '°.' | grep -Eo -e '-?[[:digit:]].*'

或者,在单个 grep 表达式中:

curl -s wttr.in/Amsterdam?T | grep -m 1 -Eo -e '-?[[:digit:]].*°.+'

这个输出是

5–8 °C

现在,如果你想要一个范围内的平均值,你可以写一个这样的函数:

cur_temp () {
    # Get current temperature into variable
    local cur=$(curl -s wttr.in/Amsterdam?T \
        | grep -m 1 -Eo -e '-?[[:digit:]].*°.')

    # Check if it is a range
    if [[ $cur == *..* ]]; then

        # Use regex to extract temperature values
        local re='(-?[[:digit:]]+)\.\.([[:digit:]]+).*°(.)'
        [[ $cur =~ $re ]]
        local lower=${BASH_REMATCH[1]}
        local upper=${BASH_REMATCH[2]}
        local unit=${BASH_REMATCH[3]}

        # Calculate average (truncates to integers)
        cur="$(( (lower + upper) / 2 )) °$unit"
    fi

    echo "$cur"
}

如果我们在之前返回一个范围的结果上调用此函数,我们现在只得到平均值(截断为整数):

$ cur_temp
6 °C

非范围和以前一样。

这可以针对位置进行参数化,就像您从 wttr.in/:bash.function 获得的示例函数一样。

【讨论】:

  • 或者,使用curl -A "Mozilla/5.0" wttr.in/Amsterdam 并处理返回的 HTML 而不是终端转义序列...
  • 这很棒。我真的需要更多地学习 sed 和正则表达式。顺便说一句,我唯一添加的是sed -e 's/[[:space:]]*$//' 来修剪尾随空格。感谢您的帮助!
  • ?T 附加到 URL 可以消除终端序列。请参阅wttr.in/:help 了解更多信息。
  • wttr.in 将温度显示的格式从“10-15 °”更改为“10..15 °”。我已提交修改以更新脚本以处理此问题。
  • @CodeFriendly 谢谢!我通过删除unit 周围的花括号来“改进”它,但这只是我个人的偏好。在任何情况下,都会在您的编辑历史记录中显示为已批准。
【解决方案2】:

我可以在 i3block 中用这条简单的线添加 Temp、H、P 和 Wind:

[weather]
full_text=
command=curl wttr.in/-31.82,-60.52\?format\="%t%20|%20%h%20|%20%P%20|%20%w"
interval=1800

这是一种斯巴达式的美:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-01-11
    • 2017-11-02
    • 1970-01-01
    • 1970-01-01
    • 2023-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多