Add leading spaces to a list of numbers?

Viewed 73

I have a list of numbers I wish to display in a way that lines them up, e.g.

xxxxxx    1 of 100
xxxxxx    2 of 100
...
xxxxxx   10 of 100
...
xxxxxx   99 of 100
xxxxxx  100 of 100

As shown by this example code---i.e. I'm talking about the part inside the while loop---rather than coding an if condition for every possible circumstance, is there a better solution to adding the necessary leading spaces to the $current variable, so that there's always at least a two space gap on the output of the echo line?

Here's my code up to this point:

#!/bin/bash

counter=1
totallines=${1}
example="xxxxxx"

while [[ $counter -le $totallines ]]; do
    # set up pretty formatting (leading spaces)
        if [ "$counter" -le 9 ]; then
            current="   $counter"
        # two digit formatting 
        elif [ "$counter" -ge 10 ] && [ "$counter" -le 99 ]; then
            current="  $counter"
        # three digit formatting
        elif [ "$counter" -ge 99 ] && [ "$counter" -le 999 ]; then
            current=" $counter"
        # beyond four digit formatting
        else
            current="$counter"
        fi
    echo "${example} $current of $totallines"
    counter=$(($counter +1))
done

Some examples illustrating lists of different lengths:

Desired output

xxxxxx   1 of 10
...
xxxxxx  10 of 10
xxxxxx     1 of 1000
...
xxxxxx  1000 of 1000
xxxxxx      1 of 10000
...
xxxxxx  10000 of 10000
xxxxxx       1 of 100000
...
xxxxxx  100000 of 100000

Actual output

xxxxxx     1 of 10
...
xxxxxx    10 of 10
xxxxxx     1 of 1000
...
xxxxxx 1000 of 1000
xxxxxx     1 of 10000
...
xxxxxx  9999 of 10000
xxxxxx  10000 of 10000
xxxxxx    1 of 100000
...
xxxxxx 99999 of 100000
xxxxxx 100000 of 100000

Any ideas?

Requisites are that it fits within the already existing loop above (which is a simplification of the loop I'm trying to work this solution into).

Thanks!

1 Answers

You can use printf for this:

totallines=${1?needs an argument}
something="texthere"

for ((counter=1; counter <= totallines; counter++)); do
   printf "%s %*d of %d\n" \
      "$something" $((${#totallines}+1)) $counter $totallines
done

and run it as:

bash script.sh 10

xxxxxx   1 of 10
xxxxxx   2 of 10
xxxxxx   3 of 10
xxxxxx   4 of 10
xxxxxx   5 of 10
xxxxxx   6 of 10
xxxxxx   7 of 10
xxxxxx   8 of 10
xxxxxx   9 of 10
xxxxxx  10 of 10

Code Demo

Details:

  • for loop runs from 1 to given totallines (passed as argument)
  • printf prints formatted output.
  • %*d prints counter with width of given argument to get alignment right. Given argument is $((${#totallines}+1)) which is length of $totallines + 1
Related