Bash变量数学扩展不适用于printf

时间:2018-03-06 07:08:00

标签: bash

我正在尝试获取一个格式化的数字,每次通过while循环都会递增。

我有fnum=$(printf "%03d" $((++num)) ),但数字没有增加。 fnum是“000”并且仍然存在。

当然num=$((++num)) ; fnum=$(printf "%03d" $num)有效,但我想知道为什么第一个没有增加数字。

2 个答案:

答案 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