如何使用bash从wttr.in卷曲结果中获取当前平均温度?

4 bash grep curl tmux

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

curl wttr.in/Amsterdam
Run Code Online (Sandbox Code Playgroud)

我返回了大量数据,并且希望将其用作tmux段,因此我将其范围缩小到仅提及温度(即当前温度)的范围:

curl wttr.in/Amsterdam | grep -m 1 °C
Run Code Online (Sandbox Code Playgroud)

有时返回一个范围:

_ /"".-.     4 – 7 °C
Run Code Online (Sandbox Code Playgroud)

有时是一个温度:

_ /"".-.     13 °C
Run Code Online (Sandbox Code Playgroud)

因此,它前面仍然有一些垃圾,有时它返回一个范围而不是一个温度。有谁知道我可以缩小范围以始终返回单个温度(如果有两个值则取平均值)而没有前面的文本吗?

Ben*_* W. 5

wttr.in现在支持自定义格式的单行输出,因此

curl wttr.in/Amsterdam?format=%t
Run Code Online (Sandbox Code Playgroud)

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


先前版本的答案

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

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

$ 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       $
Run Code Online (Sandbox Code Playgroud)

呈现如下:

wttr.in的渲染输出

因此,我们不能仅从第一个数字中提取所有内容,因为由于转义序列,该内容几乎涵盖了整行。

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

$ curl -s wttr.in/Amsterdam?T | grep -m 1 '°.' | cat -A
  _ /"".-.     5-8 M-BM-0C         $
Run Code Online (Sandbox Code Playgroud)

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

curl -s wttr.in/Amsterdam?T | grep -m 1 '°.' | grep -Eo -e '-?[[:digit:]].*'
Run Code Online (Sandbox Code Playgroud)

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

curl -s wttr.in/Amsterdam?T | grep -m 1 -Eo -e '-?[[:digit:]].*°.+'
Run Code Online (Sandbox Code Playgroud)

这个的输出是

5–8 °C
Run Code Online (Sandbox Code Playgroud)

现在,如果您只想获得平均值,就可以编写一个函数,如下所示:

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"
}
Run Code Online (Sandbox Code Playgroud)

如果我们在以前返回范围的结果上调用此函数,则现在只获取平均值(截断为整数):

$ cur_temp
6 °C
Run Code Online (Sandbox Code Playgroud)

非范围与以前相同。

可以将其参数化为位置,就像从中获得的示例函数一样wttr.in/:bash.function

  • 在URL后面加上`?T`摆脱了终端序列。有关更多信息,请参见http://wttr.in/:help。 (2认同)