问题
In my bash script, I set-up the following operations
year=0050
echo $(printf %04d $year)
>0040
I do not understand why 0040 is returned instead of 0050. I eventually found that to get the system to print 0050 correctly, I will have to do this instead.
year=50
echo $(printf %04d $year)
>0050
Are there any insights as to why the first case happens?
回答1:
It's because numbers with a leading zero are interpreted as octal by Bash, and octal 50 is decimal 40.
To fix it, you can either strip the zeros with a parameter expansion:
$ printf '%04d\n' "${year##+(0)}"
0050
I've dropped the echo $(...)
construct and inserted a newline in the formatting string instead.
Notice that the +(0)
pattern requires the extglob
shell option (shopt -s extglob
).
Alternatively (and more portably), you can convert the number with an arithmetic expansion first:
% printf '%04d\n' "$(( 10#$year ))"
0050
This uses the base#n
notation to indicate that n
(in our case: $year
) is in base 10 and not octal.
来源:https://stackoverflow.com/questions/46280429/strange-behavior-when-fixing-integer-lengths-in-bash