194

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

for (( num=1; num<=5; num++ ))
do
 echo $num
done

哪个输出:

1
2
3
4
5

我试图让它产生输出(在 $num 之前添加前导零):

01
02
03
04
05

不做:

echo 0$num
4

7 回答 7

324

使用以下语法:

$ for i in {01..05}; do echo "$i"; done
01
02
03
04
05

免责声明:前导零仅适用于>=bash-4.

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

$ foo=$(printf "%02d" 5)
$ echo "${foo}"
05
于 2013-08-27T08:37:25.753 回答
64

seq -w将检测最大输入宽度并标准化输出的宽度。

for num in $(seq -w 01 05); do
    ...
done

在撰写本文时,这不适用于最新版本的 OSX,因此您可以安装 macports 并使用其版本seq,或者您可以明确设置格式:

seq -f '%02g' 1 3
    01
    02
    03

但是考虑到这样一个简单问题的格式规范很丑陋,我更喜欢 Henk 和 Adrian 给出的解决方案,它只使用 Bash。由于没有通用的“unix”版本的 Bash,Apple 无法解决这个问题:

echo {01..05}

或者:

for number in {01..05}; do ...; done
于 2013-08-27T08:05:29.953 回答
46

使用printf命令进行0填充:

printf "%02d\n" $num

你的 for 循环将是这样的:

for (( num=1; num<=5; num++ )); do printf "%02d\n" $num; done
01
02
03
04
05
于 2013-08-27T08:05:02.827 回答
28

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

您仍然可以使用printf

for num in {1..5}
do
   value=$(printf "%02d" $num)
   ... Use $value for your purposes
done
于 2013-08-27T15:17:35.260 回答
12

从 bash 4.0 开始,您可以使用带有固定长度字符串的大括号扩展。请参阅下面的原始公告。

它会做你需要的,并且不需要外壳外部的任何东西。

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

for num in {01..05}
do
  echo $num
done
01
02
03
04
05

更改,发布 bash-4.0,第 3 节

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

. . .

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

于 2013-08-27T09:05:37.490 回答
10

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

于 2013-08-27T08:04:45.407 回答
3

请注意:我在不同版本的 bash 上经历了不同的行为:

  • 版本 3.1.17(1)-release-(x86_64-suse-linux) 和
  • 版本 4.1.17(9)-release (x86_64-unknown-cygwin))

对于前者(3.1)for nn in (00..99) ; do ...可以工作但for nn in (000..999) ; do ...不能工作,两者都可以在 4.1 版上工作;尚未测试 printf 行为(bash --version提供版本信息)

干杯,简

于 2015-02-05T18:11:01.027 回答