Bash变量数学扩展不适用于printf
我试图通过while循环获得一个每次递增的格式化数字 我得到了Bash变量数学扩展不适用于printf,bash,Bash,我试图通过while循环获得一个每次递增的格式化数字 我得到了fnum=$(printf“%03d”$(++num))但是这个数字没有增加fnum为“000”,并保持不变 当然num=$(++num));fnum=$(printf“%03d”$num)有效,但我想知道为什么第一个不增加数字。使用: $(printf "%03d" $((++num))) $()中的命令在子shell中运行,因此对其中num变量的更改不会带回父shell 对于工作版本,在当前shell的上下文中执行num=$(+
fnum=$(printf“%03d”$(++num))
但是这个数字没有增加fnum
为“000”,并保持不变
当然num=$(++num));fnum=$(printf“%03d”$num)
有效,但我想知道为什么第一个不增加数字。使用:
$(printf "%03d" $((++num)))
$()
中的命令在子shell中运行,因此对其中num
变量的更改不会带回父shell
对于工作版本,在当前shell的上下文中执行num=$(++num))
,因此修改num
当然,返回到num
没有什么意义,因为++
的副作用正在改变num
,所以您可以执行以下操作:
((++num)) ; fnum=$(printf "%03d" $num)
您可以完全避免启动子shell,只需使用内部bash
功能,如果您需要经常这样做,这将产生很大的不同(a):
(a) 如以下脚本所示:
rm -f qq[12]
time (
var=0
while [[ ${var} -lt 99999 ]] ; do
((++var))
svar=$(printf "%05d" ${var})
echo ${svar}
done
) >>qq1
time (
var=0
while [[ ${var} -lt 99999 ]] ; do
((++var))
svar=00000${var}
svar=${svar: -5}
echo ${svar}
done
) >>qq2
第一个代码段需要9秒多一点的CPU时间(用户+系统)来运行,第二个代码段在大约一秒钟内完成(如果您测量挂钟时间,差异甚至更明显,因为需要启动“子shell中的printf”的许多副本):
存储
printf
的输出首先不需要comamnd替换($(..)
),使用-v
选项将其存储在变量中
printf -v fnum "%03d" $((++num))
另外,
num
变量在子shell中更新,$(..)
在单独的shell中运行命令。num
incremented的值将永远不会反映回父shell。我也是svar=00000${var}的粉丝;svar=${svar:-5}
机制。不过有一个陷阱。对于负值,它变得很奇怪。如果数字保证为正数,那么就没有问题。:facepalm:当然是在一个子外壳中。谢谢你的-v
提示。@TonyWilliams:这是常有的事;)
real 0m30.875s
user 0m0.320s
sys 0m9.144s
real 0m1.008s
user 0m0.924s
sys 0m0.080s
printf -v fnum "%03d" $((++num))