44

在文本文件 test.txt 中,我有以下信息:

sl-gs5 desconnected Wed Oct 10 08:00:01 EDT 2012 1001

我想通过下一个命令行提取事件的时间:

hour=$(grep -n sl-gs5 test.txt | tail -1 | cut -d' ' -f6 | awk -F ":" '{print $1}')

我得到了“08”。当我尝试加 1 时,

 14 echo $((hour+1))

我收到下一条错误消息:

./test2.sh: line 14: 08: value too great for base (error token is "08")

如果 Bash 中的变量没有类型,为什么?

4

8 回答 8

105

见算术评估man bash

以 0 开头的常量被解释为八进制数。

您可以通过参数扩展删除前导零:

hour=${hour#0}

或强制 base-10 解释:

$((10#$hour + 1))
于 2012-10-10T14:29:00.737 回答
17

我称之为黑客,但鉴于你只处理小时值,你可以做

 hour=08
 echo $(( ${hour#0} +1 ))
 9
 hour=10 
 echo $(( ${hour#0} +1))
 11

风险很小。

IHTH。

于 2012-10-10T14:31:08.980 回答
10

你也可以使用bc

hour=8
result=$(echo "$hour + 1" | bc)
echo $result
9
于 2014-08-09T13:07:58.157 回答
3

这是一种简单的方法,尽管不是获取字符串的 int 值的最漂亮的方法。

hour=`expr $hour + 0`

例子

bash-3.2$ hour="08"
bash-3.2$ hour=`expr $hour + 0`
bash-3.2$ echo $hour
8
于 2016-05-07T19:11:59.803 回答
3

简而言之:为了在 bash 中处理“前导零”数字(第一个非零之前的任何 0 数字) - 使用bc任意精度计算器语言

例子:

a="000001"
b=$(echo $a | bc)
echo $b

输出:1

来自 Bash 手册:

“bc 是一种通过交互式执行语句支持任意精度数的语言。语法与 C 编程语言有一些相似之处。标准数学库可通过命令行选项获得。如果需要,定义数学库在处理任何文件之前。bc 首先按列出的顺序处理命令行中列出的所有文件中的代码。处理完所有文件后,bc 从标准输入中读取。所有代码在读取时执行。(如果文件包含停止处理器的命令,bc 永远不会从标准输入中读取。)”

于 2019-09-19T14:40:39.053 回答
2

由于小时数始终为正数且始终为 2 位数,因此您可以在其前面设置 1 并减去 100:

echo $((1$hour+1-100))

这相当于

echo $((1$hour-99))

一定要评论这样的体操。:)

于 2018-01-30T23:42:54.147 回答
1

sed怎么样?

hour=`echo $hour|sed -e "s/^0*//g"`
于 2017-10-22T05:46:26.530 回答
0

前导 0 导致 bash 试图将您的数字解释为八进制数,但八进制数是 0-7,因此 8 是无效标记。

如果我是你,我会添加一些逻辑来删除前导 0,添加一个,如果结果小于 10,则重新添加前导 0。

于 2017-01-21T20:01:38.123 回答