使用 bash“双括号”算术扩展,数学因前导零而失败

使用 bash“双括号”算术扩展,数学因前导零而失败

我有一个处理小时和分钟的简单脚本。

如果我想计算自午夜以来有一个字符串 s 的分钟数,hh:mm我尝试分割字符串然后做hh * 60 + mm

我的问题是,虽然

$ (( tot = 12 * 60 + 30 ))
$ echo $tot
750

反而

$ (( tot = 09 * 60 + 30 ))
bash: ((: tot = 09: value too great for base (error token is "09")

据我了解,字符串09并不是以 10 为基数的数字。

有没有比简单地删除字符串中的前导零更好的方法?

答案1

h=09; m=30;(( tot = 10#$h * 60 + 10#$m )); echo $tot  

前面的数字 #是基数(或基数)
后面的数字#必须对基数有效
输出始终为十进制
您可以使用以下基数2 至 64(在 GNU bash 4.1.5 中)

请注意,Bash 要求 之前有一个前导减号10#,因此如果您的号码有减号,则10#直接添加前缀将不起作用。

正如所指出的恩佐伊布,旧的替代方案$[expression]已被弃用,因此最好使用 POSIX 兼容的$((expr))

$(( 2#1)) ==  1
$((16#F)) == 15
$((36#Z)) == 35  

我不确定之后使用了哪些“数字”Z

答案2

Shell 算术表达式中数字常量的前导零表示八进制常量。

这是删除初始零的一种便携式方法:

h=${h#${h%%[!0]*}}; [ -n "$h" ] || h=0

在 bash、ksh 或 zsh 中,您可以明确指定基数 10$((10#$h))

相关内容