这是我的 bash 脚本 - 我只想用零填充一组数字:
printf "%04d" "09"
printf "%04d" "08"
printf "%04d" "07"
printf "%04d" "06"
输出:
./rename.sh: line 3: printf: 09: invalid number
0000
./rename.sh: line 4: printf: 08: invalid number
0000
0007
0006
什么...?
只有 09 和 08 导致了问题:我的序列中的所有其他数字似乎都正常。
如果你的
"09"
在变量中,你可以这样做
a="09"
echo "$a"
echo "${a#0}"
printf "%04d" "${a#0}"
为什么这有帮助?那么,以
0
开头但第二位没有 x
的数字文字将被解释为八进制值。
八进制值只有数字
0
..7
,8
和9
未知。
"${a#0}"
剥离一个前导 0
。然后可以将结果值输入到 printf
,然后以 4 位数字的形式正确打印它,并带有 0
前缀。
如果您必须期望获得诸如
"009"
之类的值,事情会变得更加复杂,因为您必须使用一个循环来消除开始时所有多余的 0
,或者使用 extglob
表达式,如中提到的评论。
Bash 的数值算术评估语法
(( ... ))
可以使用以下语法转换为基数 10(从而确保正确的解释):(( 10#$var ))
。或者,对于原始数字:(( 10#08 ))
。非常简单和干净,可以在任何你确定基数应该是 10 的地方使用,但不能保证不包含前导零。
因此,在您的示例中,如下所示:
printf "%04d\n" $(( 10#09 ))
printf "%04d\n" $(( 10#08 ))
printf "%04d\n" $(( 10#07 ))
printf "%04d\n" $(( 10#06 ))
产生以下输出:
0009
0008
0007
0006
使用此语法,由于您随后使用变量的值而不是变量本身,因此增量器
(( var++ ))
和减量器 (( var-- ))
将不起作用,但仍然可以相对干净地实现为 var=$(( 10#var + 1 ))
和 var=$(( 10#var - 1 ))
分别是
。
我第一次遇到这个解决方案在这里,但是这个类似的堆栈溢出问题的答案也演示了它。
以“0”开头的数字被视为八进制(即以 8 为基数)。因此,“8”和“9”不是有效数字。
请参阅 http://www.gnu.org/software/bash/manual/bashref.html#Shell-Arithmetic。
此行为是从 C 等语言继承的。
浮点数的处理方式不同:
printf "%04.f" "009"
这给出了正确的输出,而无需处理任何花哨的 bashism(根据 @Oli Charlesworth 的回答,0*** 被视为八进制,但我相信 Bash 忽略浮点数的八进制/十六进制标识符)
护理!!
07
工作正常:
printf 'Entered number: %d.\n' 07
Entered number: 7.
好的,但是:
printf 'Entered number: %d.\n' 07 070 0700
Entered number: 7.
Entered number: 56.
Entered number: 448.
因为在整数前面加上
0
是传统的快捷方式,意味着 数字是八进制。
printf "%d\n" 010 0100
8
64
printf "%o\n" 8 64 0100
10
100
100
printf "%04o\n" 8 64 0100
0010
0100
0100
10#
在bash下,你可以通过这种方式精确,其中base用于数字
echo $(( 10#0100))
100
echo $(( 10#0900))
900
echo $(( 10#0900 ))
900
和
echo $(( 8#100 ))
64
echo $(( 2#100 ))
4
当然!
世界上只有10种人:懂二进制的和不懂二进制的。
为此,您必须使用变量
a=09
echo ${a#0}
9
这会很好地工作,直到你只剩下一个
0
为止。
a=0000090
echo ${a#*0}
000090
echo ${a##0}
000090
为此,您可以使用
extglob
功能:
echo ${a##*(0)}
0000090
shopt -s extglob
echo ${a##*(0)}
90
floating point
与 printf
printf "%.0f\n" 09
9
我喜欢使用
-v
的 printf
选项来设置一些变量:
printf -v a %.0f 09
echo $a
9
或者即使
a=00090
printf -v a %.0f $a
echo $a
90
添加
*
使 shell 参数扩展匹配变得贪婪(例如,参见 Shell Tipps:使用内部字符串处理)!
# strip leading 0s
- a="009"; echo ${a##0}
+ a="009"; echo ${a##*0}
如果
a=079
首先,通过删除尾随零
a=`echo $a | sed 's/^0*//'`
然后进行零填充
printf "%04d" $a
从八进制转换为十进制更简单:
nm=$((10#$nm))