How to format output of script to have equal number of spaces

Here's my script:

#!/bin/bash
declare -a a=(`ls`)
declare -a b=()
declare -a sorted_arr=()

var =0

while [ -n "${a[$var]}" ]
do

    echo "${a[$var]:0:10}              |"
    var=`expr $var + 1`

done

This script produces inconsistent spacing

another_fi              |
f2.txt              |
file1.txt              |
file3.txt              |

What I want is for vertical pipeline symbols to be aligned

another_fi             |
f2.txt                 |
file1.txt              |
file3.txt              |

The main reason is because your echo command takes x number of characters from variable and pads 14 spaces. That means total number of chars in output string space won't be consistent.

Instead , you might want to use printf with width specifier %-10s for left padding like this:

bash-4.3$ for i in "${a[@]}"; do     printf "%-10s%-4s|\n"  "${i:0:10}" " "; done
1.wav         |
2.wav         |
3.wav         |
input.txt     |

This way whatever variable you have will be made to fit within 10 characters,and to those 10 characters we pad 4. - sign makes each string left justified.

Number -10 in %-10s should remain the same to ensure that even if the file is shorter than 10 characters, we still get a 10 character string with spaces padded. But %-4s part can be varied. For instance in the example above, %-4s will have 4 spaces there, but if we want to have 14 spaces, then use %-14s.


Note that it's generally recommended against of parsing output of ls, which is exactly what you're doing. As alternative, we can use find command with while IFS= read -r -d '' structure like this:

bash-4.3$ find -maxdepth 1 -type f -print0 | while IFS= read -r -d '' file;
> do
>     printf "%-10s%-4s|\n"  "${file:0:10}" " "
> done
./3.wav       |
./1.wav       |
./2.wav       |
./.swp        |
./input.tx    |

Note that find is recursive, so it works on sub-directories as well. If you want to avoid that, use -maxdepth 1 option.

Note that find also has its own -printf option, which may be more efficient to have everything done via one process than two ( that's find plus the subshell in which while runs ):

$ find /bin -type f -printf "%-15f|\n" 2>/dev/null | head -n 5
hostname       |
nc.traditional |
fusermount     |
loadkeys       |
zless          |

Ideally what I'd suggest is write everything to temporary file, figure out the longest line ( aka longest filename in the file ) and pad however many spaces you want to there accordingly.