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

neu*_*ino 6 shell bash arithmetic

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

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

我的问题是,虽然

$ (( tot = 12 * 60 + 30 ))
$ echo $tot
750
Run Code Online (Sandbox Code Playgroud)

反而

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

据我了解,字符串09不应作为基数为 10 的数字。

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

Pet*_*r.O 13

h=09; m=30;(( tot = 10#$h * 60 + 10#$m )); echo $tot  
Run Code Online (Sandbox Code Playgroud)

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

正如enzoyib所指出的, $[expression] 的旧替代方案已被弃用,因此最好使用符合 POSIX 的$((expr))

$(( 2#1)) ==  1
$((16#F)) == 15
$((36#Z)) == 35  
Run Code Online (Sandbox Code Playgroud)

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

  • +1,但来自 bash 的手册页:“旧格式 `$[expression]` 已弃用,将在即将推出的 bash 版本中删除。”。最好使用符合 POSIX 的 `$((expr))`。 (3认同)

Gil*_*il' 5

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

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

h=${h#${h%%[!0]*}}; [ -n "$h" ] || h=0
Run Code Online (Sandbox Code Playgroud)

在bash和ksh或zsh的,你可以明确地指定基地10$((10#$h))