【问题标题】:How to add leading zeros for for-loop in shell? [duplicate]如何在shell中为for循环添加前导零? [复制]
【发布时间】: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}.
  • stackoverflow.com/a/18469460/188159 应该设置为答案。

标签: bash for-loop


【解决方案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

免责声明:前导零仅适用于 &gt;=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 将用作另一个程序的参数,但让我看看我能用这个做什么。
    • 请清楚地解释你想要做什么,而不是我能建议一个更合适的答案。
    • @BruceBlacklaws printf 在 shell 中用于从参数列表创建字符串。输出到屏幕只是默认设置。事实上,shell 管道是函数式编程的终极示例——只是输入、输出,没有副作用。 ;-)
    【解决方案7】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-12-30
      • 1970-01-01
      • 1970-01-01
      • 2021-11-26
      相关资源
      最近更新 更多