我正在尝试获取一个格式化的数字,每次通过while循环都会递增。
我有fnum=$(printf "%03d" $((++num)) )
,但数字没有增加。 fnum
是“000”并且仍然存在。
当然num=$((++num)) ; fnum=$(printf "%03d" $num)
有效,但我想知道为什么第一个没有增加数字。
答案 0 :(得分:5)
您首先不需要comamnd-substitution($(..)
)来存储printf
的输出,使用-v
选项将其存储在变量中
printf -v fnum "%03d" $((++num))
此外,num
变量在子shell中更新,$(..)
在单独的shell中运行命令。 num
递增的值将永远不会反映在父shell中。
答案 1 :(得分:2)
使用:
$(printf "%03d" $((++num)))
$()
内的命令在子shell 中运行,因此对num
变量的更改不会被传回父shell。
使用工作版本,num=$((++num))
在当前 shell的上下文中执行,因此num
被修改。
当然,分配回num
毫无意义,因为++
的副作用无论如何正在改变num
,所以你可以这样做:
((++num)) ; fnum=$(printf "%03d" $num)
你可以完全避免启动子shell并只使用内部bash
内容,如果你需要做很多事情,那将会产生很大的影响(a )功能:
((++num)) ; fnum=000${num} ; fnum=${fnum: -3} ; doSomethingWith ${fnum}
(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时间(用户+系统)才能运行,第二个片段在大约一秒内完成(如果您测量挂钟时间,差异甚至更多发音,因为需要启动许多“子壳中的printf”副本:
real 0m30.875s
user 0m0.320s
sys 0m9.144s
real 0m1.008s
user 0m0.924s
sys 0m0.080s