如何通过bash获得wttr.in卷曲结果的当前平均温度?

wttr.in可以通过curling wttr.in给你天气:

curl wttr.in/Amsterdam

我返回一个大的数据列表,我想将它用作tmux段,所以我把它缩小到第一次提到温度(这是当前的温度):

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

有时会返回一个范围:

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

有时一个温度:

_ /"".-.     13 °C

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

解决方法

这样做的主要困难是服务返回终端转义码,这使得处理起来很麻烦.这就是你真正得到的:

$curl -s wttr.in/Amsterdam | grep -m 1 '°C' | 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       $

它呈现如下:

Rendered output from wttr.in

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

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

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

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

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

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

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

这个的输出

5–8 °C

现在,如果你只想获得一个范围的平均值,你可以写一个这样的函数

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

    # 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]}

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

    echo "$cur"
}

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

$cur_temp
6 °C

非范围与以前相同.

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

相关文章

用的openwrt路由器,家里宽带申请了动态公网ip,为了方便把2...
#!/bin/bashcommand1&command2&wait从Shell脚本并行...
1.先查出MAMP下面集成的PHP版本cd/Applications/MAMP/bin/ph...
1、先输入locale-a,查看一下现在已安装的语言2、若不存在如...
BashPerlTclsyntaxdiff1.进制数表示Languagebinaryoctalhexa...
正常安装了k8s后,使用kubect工具后接的命令不能直接tab补全...