如何在shell中为for循环添加前导零?

Bru*_*aws 124 bash for-loop

我有一个循环的基本数字,它在每次迭代时将变量num递增1 ...

for (( num=1; num<=5; num++ ))
do
 echo $num
done
Run Code Online (Sandbox Code Playgroud)

哪个输出:

1
2
3
4
5
Run Code Online (Sandbox Code Playgroud)

我正在尝试让它产生输出(在$ num之前加上前导零):

01
02
03
04
05
Run Code Online (Sandbox Code Playgroud)

没有做:

echo 0$num
Run Code Online (Sandbox Code Playgroud)

Adr*_*rth 194

使用以下语法:

$ for i in {01..05}; do echo "$i"; done
01
02
03
04
05
Run Code Online (Sandbox Code Playgroud)

如果您想使用printf,没有什么可以阻止您将其结果放入变量以供进一步使用:

$ foo=$(printf "%02d" 5)
$ echo "${foo}"
05
Run Code Online (Sandbox Code Playgroud)

免责声明:这只适用于>=bash-4.

  • 不幸的是,{01..05}不适用于旧版本的bash.我在服务器上使用bash 3.2.51并且将打印数字而不带前导零.在4.2.37的桌面上,它确实运行良好. (7认同)
  • 如果您想使用“-w”填充到最宽的数字宽度,@SRG“seq”可以自行填充,此外您的示例无效,因为它错过了“do”。操作方法如下:`for i in \`seq -w 1 50\`; 回显 $i; 完成` (3认同)
  • 最好的答案,它避免使用笨拙的外部命令(如'seq',在正确的Bash中没有必要).帮助过我. (2认同)

pio*_*ojo 45

seq -w 将检测宽度并将其标准化.

for num in $(seq -w 01 05); do
    ...
done
Run Code Online (Sandbox Code Playgroud)

显然这不适用于最新版本的iOS,因此您可以安装macport并使用其版本seq,也可以显式设置格式:

seq -f '%02g' 1 3
    01
    02
    03
Run Code Online (Sandbox Code Playgroud)

但鉴于这种简单问题的格式规范的丑陋,我更喜欢Henk和Adrian提供的解决方案,它只使用了Bash.苹果无法解决这个问题,因为没有通用的"unix"版本的Bash:

echo {01..05}
Run Code Online (Sandbox Code Playgroud)

要么:

for number in {01..05}; do ...; done
Run Code Online (Sandbox Code Playgroud)

  • 只是fyi`seq`在OSX上不存在 (3认同)
  • 它在我的机器上(OS X 10.7.5)。该手册页仅可追溯到2010年,因此(相对)是最近的新增内容。 (2认同)
  • 尝试给seq一个格式字符串.`seq -f'%02g'1 5` (2认同)

anu*_*ava 31

使用printf命令来0填充:

printf "%02d\n" $num
Run Code Online (Sandbox Code Playgroud)

你的for循环将是这样的:

for (( num=1; num<=5; num++ )); do printf "%02d\n" $num; done
01
02
03
04
05
Run Code Online (Sandbox Code Playgroud)

  • shell中的@BruceBlacklaws`printf`用于从参数列表创建字符串.输出到屏幕只是默认值.事实上,shell管道是函数式编程的最终例子 - 只是输入,输出,没有副作用.;-) (3认同)

Dav*_* W. 17

我对将它输出到屏幕不感兴趣(这就是printf主要用于的,对吧?)变量$ num将被用作另一个程序的参数,但是让我看看我能用它做些什么.

你仍然可以使用printf:

for num in {1..5}
do
   value=$(printf "%02d" $num)
   ... Use $value for your purposes
done
Run Code Online (Sandbox Code Playgroud)

  • 这可行,但产生子shell是昂贵的.对于大序列,可能需要很长时间. (3认同)

Hen*_*eld 10

从bash 4.0开始,您可以使用具有固定长度字符串的Brace Expansion.请参阅下面的原始公告.

它将完成你所需要的,并且不需要shell外部的任何东西.

$ echo {01..05}
01 02 03 04 05

for num in {01..05}
do
  echo $num
done
01
02
03
04
05
Run Code Online (Sandbox Code Playgroud)

更改,发布bash-4.0,第3部分

这是自bash-3.2发布以来添加到bash-4.0的新功能的简洁描述.

...

ž.大括号扩展现在允许对填充扩展数值进行零填充,并添加适当数量的零以确保所有值包含相同的位数.


Ben*_*oit 7

为什么不printf '%02d' $num呢?请参阅help printf此内部bash命令.