问题
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