如何在shell中为for循环添加前导零? [复制]
Posted
技术标签:
【中文标题】如何在shell中为for循环添加前导零? [复制]【英文标题】:How to add leading zeros for for-loop in shell? [duplicate] 【发布时间】:2013-08-29 21:17:15 【问题描述】:我有一个基本数字 for 循环,它在每次迭代中将变量 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
【问题讨论】:
使用适当格式的printf
。
printf from bash 有很多不好的效果,我更喜欢使用 awk,如下所示:"num=$(echo $num | awk 'printf("%02d", $1)'"
@binogure 请注意:Awk 在不同的系统上具有不同的行为。有 mawk、gawk、awk、nawk 等。我尽量不推荐它,因为我似乎只能在我正在写它的计算机上测试它。 Perl/Ruby 更兼容。
printf '%s\n' 01..05
.
***.com/a/18469460/188159 应该设置为答案。
【参考方案1】:
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。 Apple 不能搞砸,因为没有通用的“unix”版本的 Bash:
echo 01..05
或者:
for number in 01..05; do ...; done
【讨论】:
仅供参考seq
在 OSX 上不存在
它在我的机器上 (OS X 10.7.5)。手册页只能追溯到 2010 年,因此它看起来是(相对)最近添加的。
在 01 到 05 的 mac os sierra 上不起作用。但适用于 01 到 10。
尝试给 seq 一个格式字符串。 seq -f '%02g' 1 5
seq -w
确实可以轻松完成工作!【参考方案2】:
使用以下语法:
$ for i in 01..05; do echo "$i"; done
01
02
03
04
05
免责声明:前导零仅适用于 >=bash-4
。
如果您想使用printf
,没有什么可以阻止您将其结果放入变量中以供进一步使用:
$ foo=$(printf "%02d" 5)
$ echo "$foo"
05
【讨论】:
最佳答案,它避免使用笨拙的外部命令(如'seq',在适当的 Bash 中不是必需的)。帮助了我。 很遗憾,01..05 不适用于旧版本的 bash。我在使用 bash 3.2.51 的服务器上,它将打印没有前导零的数字。在我的 4.2.37 桌面上,它运行良好。 @thomanski 公平点,Changelog 声明此功能是由bash-4.0-alpha
引入的:大括号扩展现在允许对扩展的数值进行零填充,并将添加适当数量的零以确保所有值都包含相同的位数。).
@Matt 到底什么不起作用?只要您有足够新的bash
版本,就可以正常工作。
@SRG seq
如果您想使用-w
填充到最宽的数字宽度,则可以自己进行填充,此外您的示例无效,因为它错过了do
。您可以这样做:for i in `seq -w 1 50`; do echo $i; done
【参考方案3】:
从 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
CHANGES, release bash-4.0, section 3
这是对 bash-4.0 中添加的新功能的简要描述,因为 bash-3.2 的发布。
。 . .
z。大括号扩展现在允许对扩展数值进行零填充,并将添加适当数量的零以确保所有值包含相同的位数。
【讨论】:
我知道我没有指定 BASH 的哪个版本以及它在哪个平台上运行,但是这个平面在 GNU bash 版本 3.2.57(1)-release (x86_64-apple-darwin16) 上失败了跨度> @BruceBlacklaws 正确。固定长度数字是在 4.0 中添加的。包括限制。【参考方案4】:请注意: 我在不同版本的 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
给出了版本信息)
干杯,简
【讨论】:
【参考方案5】:我对将它输出到屏幕不感兴趣(这就是 printf 的主要用途,对吗?)变量 $num 将用作另一个程序的参数,但让我看看我能做什么这个。
你仍然可以使用printf
:
for num in 1..5
do
value=$(printf "%02d" $num)
... Use $value for your purposes
done
【讨论】:
这可行,但生成子shell 很昂贵。对于大序列,可能需要很长时间。【参考方案6】:使用printf
命令获得0
填充:
printf "%02d\n" $num
你的 for 循环会是这样的:
for (( num=1; num<=5; num++ )); do printf "%02d\n" $num; done
01
02
03
04
05
【讨论】:
我对将它输出到屏幕不感兴趣(这就是 printf 的主要用途,对吧?)变量 $num 将用作另一个程序的参数,但让我看看我能用这个做什么。 请清楚地解释你想要做什么,而不是我能建议一个更合适的答案。 @BruceBlacklawsprintf
在 shell 中用于从参数列表创建字符串。输出到屏幕只是默认设置。事实上,shell 管道是函数式编程的终极示例——只是输入、输出,没有副作用。 ;-)【参考方案7】:
为什么不printf '%02d' $num
?有关此内部 bash 命令,请参阅 help printf
。
【讨论】:
以上是关于如何在shell中为for循环添加前导零? [复制]的主要内容,如果未能解决你的问题,请参考以下文章