对于基值来说太大(错误令牌"09")

  • 本文关键字:令牌 错误 于基值 bash
  • 更新时间 :
  • 英文 :


当运行我的bash脚本的这一部分时,我得到了一个错误

编写脚本

value=0
for (( t=0; t <= 4; t++ ))
do
d1=${filedates[$t]}
d2=${filedates[$t+1]}
((diff_sec=d2-d1))
SEC=$diff_sec
compare=$((${SEC}/(60*60*24)))
value=$((value+compare))
done

输出

jad.sh: line 28: ((: 10#2014-01-09: value too great for base (error token is "09")
jad.sh: line 30: /(60*60*24): syntax error: operand expected (error token is "/(60*60*24)")

d1和d2是2014-01-09和2014-01-10 格式的日期

有什么解决方案吗?

在变量前面加上字符串"10#"。这迫使bash将它们视为十进制,即使前导零通常会使它们成为八进制。

什么是d1d2?它们是日期还是秒?

通常,如果您试图对包含零前缀的数字(例如09)进行算术运算,就会出现此错误。

示例:

$ echo $((09+1))
-bash: 09: value too great for base (error token is "09")

为了使用前缀为0的数字执行算术运算,您需要通过指定10#:来告诉bash使用基数为10的数字

$ echo $((10#09+1))
10

正如其他人所说,错误是由Bash将以零开头的数字序列解释为八进制数引起的。如果您可以控制创建日期值的过程,并且您使用的是date,则可以在输出格式字符串前面加一个连字符,以删除前导零填充。

不在date格式前加连字符:

$ (( $(date --date='9:00' +%H) < 10 )) && echo true || echo oops
-bash: ((: 09: value too great for base (error token is "09")
oops

date格式前加上连字符:

$ (( $(date --date='9:00' +%-H) < 10 )) && echo true || echo oops
true

来自date手册页:

默认情况下,日期用零填充数字字段。以下内容可选标志可能跟在"%"后面:

-      (hyphen) do not pad the field

d1和d2是2014-01-09和2014-01-10 格式的日期

然后

((diff_sec=d2-d1))

你期望得到什么?((diffsec=2014-01-09-2014-01-10))??

您需要先将日期转换为秒:

d1=$( date -d "${filedates[$t]}" +%s )
d2=$( date -d "${filedates[$t+1]}" +%s )
(( compare = (d2 - d1) / (60*60*24) ))
(( value += compare ))

在此处发布一些与本问题标题相关的提示,但与原始问题的详细信息没有直接关系。我意识到这在Stack Overflow上有点争议,但这些相关问题:

在bash〔duplicate〕中将八进制转换为十进制

值对于基本值太大(错误标记为"08")[重复]

指向这个,,但它们是关闭的,因此,我无法在那里发布这个答案。因此,这似乎是一个合乎逻辑的地方(至少对我来说),发布这些信息可能会帮助其他处于类似情况的人,尤其是BaSH程序员。

确保数字被视为10基数整数的另一种方法是使用printf。此命令指示printf将$num视为整数,并将其四舍五入到小数点后0位。

num="$(printf "%.0f" "$num")"

或者,如果你还想确保字符串中没有非数字字符,你可以这样做:

num="$(printf "%.0f" "${num//[!0-9]/}")"

这两个命令都将去掉前导零,并将十进制值四舍五入到最接近的整数。请注意,第一个(更简单的)解决方案适用于负数,但第二个解决方案不适用(它总是返回绝对值)。

请注意,printf向下取整,这意味着.01到0.5取整为0,而.51到.99取整为1。基本上,在这种情况下,向上取整与向下取整的区别在于printf向下取整0.5及以下。我提到这一点是因为0.5取整是一种更常见的做法。

现在,解决OP的具体场景。。。。将printfawk组合使用,可以实现单独使用

print f这个

compare=$((${SEC}/(606024))

也可以表示为

compare=$(awk -v sec=$SEC 'BEGIN { print int(sec/(60*60*24))}')

compare="$(printf "%.0f" "$(awk "BEGIN { print ( $SEC / ( 60 * 60 * 24 ) ) }")")"

同时,

值=$((值+比较))

可以计算为

value="$(printf "%.0f" "$(awk "BEGIN { print ( $value + $compare ) }")")"

算术展开表达式中不需要${}。它应该是这样的:

compare=$((SEC/(60*60*24)))

对于日期中的"mm"one_answers"dd"值,我使用以下技巧:

mm="1${date:5,2}"  # where 5 is the offset to mm in the date
let mm=$mm-100     # turn 108 into 8, and 109 into 9

相关内容

  • 没有找到相关文章

最新更新