这是我的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导致问题:我的序列中的每个其他数字似乎都没问题。
答案 0 :(得分:26)
如果您在变量中有"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
,或者{ {1}}表达式,如评论中所述。
答案 1 :(得分:20)
以“0”开头的数字被视为八进制(即基数为8)。因此,“8”和“9”不是有效数字。
请参阅http://www.gnu.org/software/bash/manual/bashref.html#Shell-Arithmetic。
此行为继承自C。
等语言答案 2 :(得分:18)
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 ))
。
我第一次遇到此解决方案here,但this answer to a similar Stack Overflow question也证明了这一点。
答案 3 :(得分:4)
只需要添加到Oli's answer,为了用零填充数字,就可以像0
一样在%
之后加上printf "%04d" "9"
:
{{1}}
答案 4 :(得分:3)
浮点的处理方式不同:
printf "%04.f" "009"
这给出了正确的输出,没有处理任何花哨的基础(根据@Oli Charlesworth的回答,0 ***被视为八进制,但我相信Bash忽略浮点数的八进制/十六进制标识符)
答案 5 :(得分:1)
添加*
使shell参数扩展与贪婪匹配(例如,参见Shell Tipps: use internal string handling)!
# strip leading 0s
- a="009"; echo ${a##0}
+ a="009"; echo ${a##*0}
答案 6 :(得分:1)
因为在整数前面加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
的{{1}}选项来设置一些变量:
printf
或者即使
printf -v a %.0f 09
echo $a
9
答案 7 :(得分:0)
从八进制转换为十进制更简单:$ nm = $(((10#$ nm))
答案 8 :(得分:0)
如果a=079
首先,通过删除尾随零
a=`echo $a | sed 's/^0*//'`
然后进行零填充
printf "%04d" $a