如何使用 bash 从 wttr.in 卷曲结果中获取当前平均温度?
How to get just current average temperature from wttr.in curl result with bash?
wttr.in 可以通过冰壶给你天气 wttr.in:
curl wttr.in/Amsterdam
我 return 有一大堆数据,我想将它用作 tmux 段,所以我将其缩小到只提到温度(即当前温度):
curl wttr.in/Amsterdam | grep -m 1 °C
有时 return 是一个范围:
_ /"".-. 4 – 7 °C
有时一个温度:
_ /"".-. 13 °C
所以它前面还有一些垃圾,它有时 return 是一个范围而不是单个温度。有谁知道我如何将其缩小到始终 return 单个温度(如果有两个值则取平均值)并且没有前面的文本?
wttr.in 现在支持自定义格式的 one-line output,所以这个
curl wttr.in/Amsterdam?format=%t
returns 只是温度,据我所知,它 returns 是单个值而不是范围。
上一个答案
基于我们必须自己修改响应的假设
这个的主要困难是服务 returns 终端转义码,这使得处理变得混乱。这就是你真正得到的:
$ 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
Non-ranges同前
这可以针对位置进行参数化,就像您从 wttr.in/:bash.function
.
获得的示例函数一样
我可以在我的 i3block 中用这条简单的线添加温度、H、P 和风:
[weather]
full_text=
command=curl wttr.in/-31.82,-60.52\?format\="%t%20|%20%h%20|%20%P%20|%20%w"
interval=1800
是斯巴达式的美女:
wttr.in 可以通过冰壶给你天气 wttr.in:
curl wttr.in/Amsterdam
我 return 有一大堆数据,我想将它用作 tmux 段,所以我将其缩小到只提到温度(即当前温度):
curl wttr.in/Amsterdam | grep -m 1 °C
有时 return 是一个范围:
_ /"".-. 4 – 7 °C
有时一个温度:
_ /"".-. 13 °C
所以它前面还有一些垃圾,它有时 return 是一个范围而不是单个温度。有谁知道我如何将其缩小到始终 return 单个温度(如果有两个值则取平均值)并且没有前面的文本?
wttr.in 现在支持自定义格式的 one-line output,所以这个
curl wttr.in/Amsterdam?format=%t
returns 只是温度,据我所知,它 returns 是单个值而不是范围。
上一个答案
基于我们必须自己修改响应的假设
这个的主要困难是服务 returns 终端转义码,这使得处理变得混乱。这就是你真正得到的:
$ 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
Non-ranges同前
这可以针对位置进行参数化,就像您从 wttr.in/:bash.function
.
我可以在我的 i3block 中用这条简单的线添加温度、H、P 和风:
[weather]
full_text=
command=curl wttr.in/-31.82,-60.52\?format\="%t%20|%20%h%20|%20%P%20|%20%w"
interval=1800
是斯巴达式的美女: