我需要循环一些值,

for i in $(seq $first $last)
do
    does something here
done

对于$first和$last,我需要它的固定长度为5。所以如果输入是1,我需要在前面加上0,这样它就变成了00001。例如,它循环到99999,但长度必须是5。

例如:00002,00042,00212,12312等等。

你知道我该怎么做吗?


当前回答

在您的特定情况下,使用-f标志使seq在输出列表时格式化数字可能是最简单的。例如:

for i in $(seq -f "%05g" 10 15)
do
  echo $i
done

将产生以下输出:

00010
00011
00012
00013
00014
00015

更一般地说,bash内置了printf,所以你可以像下面这样用0填充输出:

$ i=99
$ printf "%05d\n" $i
00099

你可以使用-v标志将输出存储在另一个变量中:

$ i=99
$ printf -v j "%05d" $i
$ echo $j
00099

请注意,printf支持与seq略有不同的格式,因此您需要使用%05d而不是%05g。

其他回答

如果序列的结尾有最大的填充长度(例如,如果你想要5个数字,命令是seq 1 10000),那么你可以为seq使用-w标志-它自己添加填充。

seq -w 1 10

会产生

01
02
03
04
05
06
07
08
09
10

你不需要awk - seq或jot单独就足够了:

% seq -f '%05.f' 6     # bsd-seq
00001
00002
00003
00004
00005
00006

% gseq -f '%05.f' 6    # gnu-seq
00001
00002
00003
00004
00005
00006

% jot -w '%05.f' 6
00001
00002
00003
00004
00005
00006

......除非你要进入bigint领域:

% gawk -Mbe '

  function __(_,___) {
      return +_<+___?___:_
  }
  BEGIN {
        _+=_^=_<_                 
      ____="%0*.f\n"   
  } {                      
       ___=__($--_, !+$++_)                
     _____=__(++_+--_, length(______=+$NF)) 
     do {                     
        printf(____,_____,___)
     }  while (___++<______) 
                                                       
  }' <<< '999999999999999999996 1000000000000000000003'

0999999999999999999996
0999999999999999999997
0999999999999999999998
0999999999999999999999
1000000000000000000000
1000000000000000000001
1000000000000000000002
1000000000000000000003

——————————————————————————————————————————————————

如果你需要打印出一个巨大的数字范围,那么这种方法可能会更快一点-

在0.049秒内打印出从1到100万的每一个整数,左零填充到9位宽 *警告:我没有多余的时间让它覆盖所有的输入范围::这只是一个接受10次方增量的概念证明

——————————————————————————————————————————————————

 ( time ( LC_ALL=C mawk2 '
 
   function jot(____,_______,_____,_,__,___,______) {
       if(____==(____^!____)) {
           return +____<+_______\
               ? sprintf("%0*.f",_______,____)\
               : +____ 
        }
        _______= (_______-=____=length(____)-\
                 (_=!(_<_)))<+_ \
                 ? "" \
                 : sprintf("%0*.f",_______,!_)
           __=_= (!(__=_+=_+_))(__=(-+--_)+(__+=_)^++_)\
                 (__+=_=(((_--^_--+_++)^++_-_^!_)/_))(__+_)
          _____= "."
     gsub(_____,"\\&&",__)
     ____—-
     do { 
         gsub(_____,__,_)
        _____=_____"." 
     } while(—____)

     gsub(_____,(_______)"&\n",_)
     sub("^[^\n]+[\n]","",_)
     sub(".$",""~"",_______)
     
     return \
     (_)(_______)\
     sprintf("%0*.f",length(_____),__<__)

   } { print jot($1,$2) }' <<< '10000000 9'
  
 ) | pvE9 ) |xxh128sum |ggXy3 | lgp3

 sleep 2
 ( time ( LC_ALL=C jot 1000000 | 
          LC_ALL=C mawk2 '{ printf("%09.f\n", $1) }' 
 
 ) | pvE9 ) |xxh128sum |ggXy3 | lgp3


     out9: 9.54MiB 0:00:00 [ 275MiB/s] [ 275MiB/s] [<=> ]
( LC_ALL=C mawk2  <<< '1000000 9'; )

0.04s user 0.01s system 93% cpu 0.049 total

e0491043bdb4c8bc16769072f3b71f98  stdin


     out9: 9.54MiB 0:00:00 [36.5MiB/s] [36.5MiB/s] [  <=> ]
( LC_ALL=C jot 1000000 | LC_ALL=C mawk2 '{printf("%09.f\n", $1)}'; )

0.43s user 0.01s system 158% cpu 0.275 total

e0491043bdb4c8bc16769072f3b71f98  stdin

当你做了1000万的时候,时差就变得很明显了:

 out9: 95.4MiB 0:00:00 [ 216MiB/s] [ 216MiB/s] [<=> ]
 ( LC_ALL=C mawk2  <<< '10000000 9'; )

 0.38s user 0.06s system 95% cpu 0.458 total

 be3ed6c8e9ee947e5ba4ce51af753663  stdin


 out9: 95.4MiB 0:00:02 [36.3MiB/s] [36.3MiB/s] [ <=> ]
 ( LC_ALL=C jot 10000000 | LC_ALL=C mawk2 '{printf("%09.f\n", $1)}'; )

 4.30s user 0.04s system 164% cpu 2.638 total
 
 be3ed6c8e9ee947e5ba4ce51af753663  stdin




 out9: 95.4MiB 0:00:02 [35.2MiB/s] [35.2MiB/s] [ <=> ]

 ( LC_ALL=C python3 -c '__=1; ___=10**7;

   [ print("{0:09d}".format(_)) for _ in range(__,___+__) ]' 

 ) | pvE9 ) | xxh128sum |ggXy3 | lgp3 ;  )

 2.68s user 0.04s system 99% cpu 2.725 total
 
 be3ed6c8e9ee947e5ba4ce51af753663  stdin

在您的特定情况下,使用-f标志使seq在输出列表时格式化数字可能是最简单的。例如:

for i in $(seq -f "%05g" 10 15)
do
  echo $i
done

将产生以下输出:

00010
00011
00012
00013
00014
00015

更一般地说,bash内置了printf,所以你可以像下面这样用0填充输出:

$ i=99
$ printf "%05d\n" $i
00099

你可以使用-v标志将输出存储在另一个变量中:

$ i=99
$ printf -v j "%05d" $i
$ echo $j
00099

请注意,printf支持与seq略有不同的格式,因此您需要使用%05d而不是%05g。

如果你只是想用0填充数字以达到固定长度,只需添加最接近10的倍数 如。对于2位数字,加10^2,然后在显示输出之前删除第一个1。

此解决方案适用于填充/格式化任意长度的单个数字,或使用for循环填充/格式化整个数字序列。

# Padding 0s zeros:
# Pure bash without externals eg. awk, sed, seq, head, tail etc.
# works with echo, no need for printf

pad=100000      ;# 5 digit fixed

for i in {0..99999}; do ((j=pad+i))
    echo ${j#?}
done

在Mac OSX 10.6.8, Bash ver 3.2.48上测试

1)。创建从1到1000的数字序列“seq”,并固定宽度“-w”(宽度由结束数字的长度决定,在本例中为1000的4位数字)。

2)。另外,使用'sed -n'选择您想要的数字(在本例中,我们选择数字1-100)。

3)。'echo'输出每个数字。数字存储在变量“i”中,使用“$”访问。

优点:这段代码非常干净。

缺点:'seq'不是所有Linux系统的本机(据我所知)

for i in `seq -w 1 1000 | sed -n '1,100p'`; 
do 
    echo $i; 
done