如何在bash中填充整数序列以使所有宽度相同?

Joh*_*ton 380 bash numbers padding

我需要循环一些值,

for i in $(seq $first $last)
do
    does something here
done
Run Code Online (Sandbox Code Playgroud)

对于$first$last,我需要它是固定长度5.所以如果输入是1,我需要在前面添加零,使它成为00001.它循环直到99999例如,但长度必须是5.

如:00002,00042,00212,012312等等.

关于我如何做到这一点的任何想法?

Dav*_*ebb 637

在您的具体情况下,虽然最简单的方法是使用-f标志来seq使数字格式化,因为它输出列表.例如:

for i in $(seq -f "%05g" 10 15)
do
  echo $i
done
Run Code Online (Sandbox Code Playgroud)

将产生以下输出:

00010
00011
00012
00013
00014
00015
Run Code Online (Sandbox Code Playgroud)

更一般地说,bashprintf一个内置的,所以你可以用零填充输出,如下所示:

$ i=99
$ printf "%05d\n" $i
00099
Run Code Online (Sandbox Code Playgroud)

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

$ i=99
$ printf -v j "%05d" $i
$ echo $j
00099
Run Code Online (Sandbox Code Playgroud)

请注意,printf支持稍微不同的格式,seq因此您需要使用%05d而不是%05g.

  • 伟大,全面的答案.一个小的修正:严格来说,`seq`支持格式字符的_subset_.`printf`支持(并且该子集包括`g`,但不包括`d`).字符"d"和"g"的行为略有不同,因为`d`将`0`-前缀数字字符串解释为_octal_数字并将它们转换为十进制,而`g`将它们视为小数.(@EdManet:这就是为什么'00026'用`d`变成'00022'的原因.值得一提的另一件事是:`seq -w`根据生成的最大数字对输出数进行_automatic_零填充. (9认同)
  • `%05g`而不是`%05d`为我修复了它._"00026"_给了我_"00022"_.谢谢! (5认同)

小智 119

你可以更容易做到

for i in {00001..99999}; do
  echo $i
done
Run Code Online (Sandbox Code Playgroud)

  • 这适用于Bash版本4.1.2(CentOS 6),但在版本3.2.25(CentOS 5)中失败.我同意这是一个更美观的方式来做到这一点! (14认同)

m_m*_*iah 81

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

seq -w 1 10
Run Code Online (Sandbox Code Playgroud)

生产

01
02
03
04
05
06
07
08
09
10
Run Code Online (Sandbox Code Playgroud)

  • 这显然是正确的答案.为什么这么少的赞成? (6认同)
  • 很简单,因为填充取决于您想要达到的最大数量.如果这是一个你永远不会知道的参数,你最终会得到多少零 (5认同)
  • 这不会给出指定的固定长度,只是所有_same_长度的结果. (5认同)

fra*_*nkc 74

使用带有"%05d"的printf例如

printf "%05d" 1
Run Code Online (Sandbox Code Playgroud)


jay*_*ngh 18

使用非常简单 printf

[jaypal:~/Temp] printf "%05d\n" 1
00001
[jaypal:~/Temp] printf "%05d\n" 2
00002
Run Code Online (Sandbox Code Playgroud)


anu*_*ava 12

像这样使用awk:

awk -v start=1 -v end=10 'BEGIN{for (i=start; i<=end; i++) printf("%05d\n", i)}'
Run Code Online (Sandbox Code Playgroud)

OUTPUT:

00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
Run Code Online (Sandbox Code Playgroud)

更新:

作为纯bash替代方法,您可以执行此操作以获得相同的输出:

for i in {1..10}
do
   printf "%05d\n" $i
done
Run Code Online (Sandbox Code Playgroud)

这样你就可以避免使用*nix所有版本seq没有的外部程序.


小智 9

我填充输出的数字(零)比我需要的更多,然后使用tail只使用我要查找的位数.请注意,您必须在尾部使用'6'来获取最后五位数:)

for i in $(seq 1 10)
do
RESULT=$(echo 00000$i | tail -c 6)
echo $RESULT
done
Run Code Online (Sandbox Code Playgroud)


小智 6

如果你想要 N 个数字,添加 10^N 并删除第一个数字。

for (( num=100; num<=105; num++ ))
do
  echo ${num:1:3}
done
Run Code Online (Sandbox Code Playgroud)

输出:

01
02
03
04
05
Run Code Online (Sandbox Code Playgroud)


小智 6

不使用外部进程分叉的一种方法是字符串操作,在一般情况下,它看起来像这样:

#start value
CNT=1

for [whatever iterative loop, seq, cat, find...];do
   # number of 0s is at least the amount of decimals needed, simple concatenation
   TEMP="000000$CNT"
   # for example 6 digits zero padded, get the last 6 character of the string
   echo ${TEMP:(-6)}
   # increment, if the for loop doesn't provide the number directly
   TEMP=$(( TEMP + 1 ))
done
Run Code Online (Sandbox Code Playgroud)

这在 WSL 上也很有效,因为分叉是一项非常繁重的操作。我有一个 110000 个文件列表,使用了printf "%06d" $NUM1 分钟多,上面的解决方案运行了大约 1 秒。


小智 5

另一种方式 :

zeroos="000"
echo 

for num in {99..105};do
 echo ${zeroos:${#num}:${#zeroos}}${num}
done
Run Code Online (Sandbox Code Playgroud)

转换任何数字的简单函数是:

function leading_zero(){

    local num=$1
    local zeroos=00000
    echo ${zeroos:${#num}:${#zeroos}}${num} 

}
Run Code Online (Sandbox Code Playgroud)