How to zero pad a sequence of integers in bash so that all have the same width?

孤人 提交于 2019-11-26 00:57:08

问题


I need to loop some values,

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

For $first and $last, i need it to be of fixed length 5. So if the input is 1, i need to add zeros in front such that it becomes 00001. It loops till 99999 for example, but the length has to be 5.

E.g.: 00002, 00042, 00212, 012312 and so forth.

Any idea on how i can do that?


回答1:


In your specific case though it's probably easiest to use the -f flag to seq to get it to format the numbers as it outputs the list. For example:

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

will produce the following output:

00010
00011
00012
00013
00014
00015

More generally, bash has printf as a built-in so you can pad output with zeroes as follows:

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

You can use the -v flag to store the output in another variable:

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

Notice that printf supports a slightly different format to seq so you need to use %05d instead of %05g.




回答2:


Easier still you can just do

for i in {00001..99999}; do
  echo $i
done



回答3:


If the end of sequence has maximal length of padding (for example, if you want 5 digits and command is "seq 1 10000"), than you can use "-w" flag for seq - it adds padding itself.

seq -w 1 10

produce

01
02
03
04
05
06
07
08
09
10



回答4:


use printf with "%05d" e.g.

printf "%05d" 1



回答5:


Very simple using printf

[jaypal:~/Temp] printf "%05d\n" 1
00001
[jaypal:~/Temp] printf "%05d\n" 2
00002



回答6:


Use awk like this:

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

OUTPUT:

00001
00002
00003
00004
00005
00006
00007
00008
00009
00010

Update:

As pure bash alternative you can do this to get same output:

for i in {1..10}
do
   printf "%05d\n" $i
done

This way you can avoid using an external program seq which is NOT available on all the flavors of *nix.




回答7:


I pad output with more digits (zeros) than I need then use tail to only use the number of digits I am looking for. Notice that you have to use '6' in tail to get the last five digits :)

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



回答8:


If you want N digits, add 10^N and delete the first digit.

for (( num=100; num<=105; num++ ))
do
  echo ${num:1:3}
done

Output:

01
02
03
04
05



回答9:


This will work also:

for i in {0..9}{0..9}{0..9}{0..9}
do
  echo "$i"
done



回答10:


Other way :

zeroos="000"
echo 

for num in {99..105};do
 echo ${zeroos:${#num}:${#zeroos}}${num}
done

So simple function to convert any number would be:

function leading_zero(){

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

}



回答11:


1.) Create a sequence of numbers 'seq' from 1 to 1000, and fix the width '-w' (width is determined by length of ending number, in this case 4 digits for 1000).

2.) Also, select which numbers you want using 'sed -n' (in this case, we select numbers 1-100).

3.) 'echo' out each number. Numbers are stored in the variable 'i', accessed using the '$'.

Pros: This code is pretty clean.

Cons: 'seq' isn't native to all Linux systems (as I understand)

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



回答12:


If you're just after padding numbers with zeros to achieve fixed length, just add the nearest multiple of 10 eg. for 2 digits, add 10^2, then remove the first 1 before displaying output.

This solution works to pad/format single numbers of any length, or a whole sequence of numbers using a for loop.

# 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

Tested on Mac OSX 10.6.8, Bash ver 3.2.48




回答13:


One way without using external process forking is string manipulation, in a generic case it would look like this:

#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

This works quite well on WSL as well, where forking is a really heavy operation. I had a 110000 files list, using printf "%06d" $NUM took over 1 minute, the solution above ran in about 1 second.



来源:https://stackoverflow.com/questions/8789729/how-to-zero-pad-a-sequence-of-integers-in-bash-so-that-all-have-the-same-width

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!