【问题标题】:Adding a zero to single digit variable将零添加到单个数字变量
【发布时间】:2011-07-03 05:11:55
【问题描述】:

如果变量小于 10,则尝试在变量前添加一个零并创建所述目录。我似乎无法正确添加零。不断导致制作02.1.201102.2.2011等。

i=0
for i in {01..31}
do
    if $i > 10
        then
            mkdir $path/02.0$i.2011
        else    
            mkdir $path/02.$i.2011
    fi
done

【问题讨论】:

标签: bash unix variables directory


【解决方案1】:

您可以将全部替换为:

for day in 0{1..9} {10..31} ; do
    mkdir ${path}/02.${day}.2011
done

同时仍然不必启动任何外部进程(循环体中可能存在的进程除外)。

这可能不是那么重要这里,因为mkdir 不是你在紧密循环中经常做的事情之一,但它很重要,如果您在bash 中编写了很多快速而肮脏的代码。

当您像我的某些脚本偶尔所做的那样执行数十万次时,创建流程会很昂贵:-)

示例,以便您可以看到它的实际效果:

pax$ for day in 0{8..9} {10..11}; do echo ${day}; done
08
09
10
11

而且,如果您有足够新的 bash 版本,它将满足您对前导数字的要求:

序列表达式采用{x..y[..incr]} 的形式,其中xy 是整数或单个字符,incr(可选增量)是整数。

当提供整数时,表达式扩展为xy 之间的每个数字,包括端点。

提供的整数可以以0 为前缀,以强制每个术语具有相同的宽度。当xy 以零开头时,shell 会尝试强制所有生成的术语包含相同数量的数字,必要时补零。

所以,在我的 Debian 6 机器上,bash 版本 4.1.5:

pax$ for day in {08..11} ; do echo ${day} ; done
08
09
10
11

【讨论】:

  • 关于支持前导零的最新 bash 版本的评论的奖励!
  • 由于某种原因,我通过 macports 安装的 bash 5.0.7 不支持前缀为 0。但是指定多个非连续增量是惊人的。
【解决方案2】:

你可以使用

$(printf %02d $i)

以您想要的格式生成数字。

for i in $(seq 0 1 31)
do
    mkdir $path/02.$(printf %02d $i).2011
done

【讨论】:

  • 我忘记了 seq.但我认为,只要seq 31 就可以了。 OP 不想要 0,firstincrement 的默认值都是 1。
  • seq -w 生成带有前导零的数字。
  • 很高兴它很容易集成到像echo "this is a $var" ->echo "this is a $(printf %03d $var)"这样的旧回显语句中
【解决方案3】:

更好:

for i in $(seq -f %02g 1 31)
do
    mkdir "$path/02.$i.2011"
done

甚至:

for i in {01..31}
do
    mkdir "$path/02.$(printf "%02d" $i).2011"
done

【讨论】:

  • 在花括号中添加另一个数字就可以了!
【解决方案4】:

在 Bash 4 中,如果您要求,大括号范围扩展将为您提供前导零:

for i in {01..31}

无需做任何其他事情。

如果您使用的是早期版本的 Bash(或 4,就此而言),则无需使用外部实用程序,例如 seq

for i in {1..31}

for ((i=1; i<=31; i++))

其中任何一个:

mkdir "$path/02.$(printf '%02d' "$i").2011"

你也可以这样做:

z='0'
mkdir "$path/02.${z: -${#i}}$i.2011"

使用 paxdiablo 的建议,您可以一次创建所有目录无需循环

mkdir "$path"/02.{0{1..9},{10..31}}.2011

【讨论】:

    【解决方案5】:

    这对你有用吗?

    zeroes="0000000"
    pad=$zeroes$i
    echo ${pad:(-2)}
    

    【讨论】:

      【解决方案6】:
      $ seq --version | head -1
      seq (GNU coreutils) 8.21
      $ seq -f "%02g" 1 10
      01
      02
      03
      04
      05
      06
      07
      08
      09
      10
      

      【讨论】:

        【解决方案7】:

        您的 if/then 语句是倒退的。大于 10 时添加 0,小于 10 时不添加。

        另一个错误是您使截止值严格大于 10,其中不包括 10,即使 10 是两位数。

        【讨论】:

          【解决方案8】:
          path=/tmp
          ruby -rfileutils -e '1.upto(31){|x| FileUtils.mkdir "'$path'/02.%02d.2011" % x}'
          

          【讨论】:

            【解决方案9】:

            这是我为一个脚本所做的,我要求一天、几天的范围、正则表达式等,默认为 paxdiablo 共享的改进正则表达式。

            for day in $days
                do if [ 1 -eq "${#day}"] ; then
                    day="0$day"
                fi
            

            我只是在我的循环开始时运行了这个,我在有问题的那天运行了一堆日志分析,埋在带有前导零的目录中。

            【讨论】:

              【解决方案10】:

              我创建了这个简单的实用程序来执行此操作,祝你好运,希望这对堆栈者有所帮助!

              for i in {1..24}
              do
              charcount=`echo $i|wc -m`
              count=`expr $charcount - 1`
              if [ $count -lt 2 ];
              then
              i="0`echo $i`"
              fi
              echo "$i"
              done
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2011-11-03
                • 1970-01-01
                • 1970-01-01
                • 2020-12-10
                • 2021-11-21
                • 1970-01-01
                • 2022-11-23
                • 2011-02-03
                相关资源
                最近更新 更多