[bash scripting] Generating a table with aligned fields

Hi everyone,

I want to write a function which calculates the space needed between fields, to generate a table with aligned fields, like when you type "ls -l", the operating system generates a table with beautifully aligned fields.

I've got this code so far:

for line in $(cat tmpSearch)
do
    line=`echo $line | tr ":" " "`
    x=0
    for field in $line
    do
        x=`expr $x + 1`
        lineLength=`eval \`echo "gawk -F: '{print \\\\$\$x}' tmpSearch | gawk '{print length}' | sort -n | tail -n 1"\``
        fLine[$x]="`eval \`echo \"echo \$field | gawk '{printf \\"%-\"$lineLength\"s\\\\\n\\",\\\\$0}'\"\``"        
    done
    echo "${fLine[@]:1}"
done

Original file: tmpSearch

000001:Mia:Miki:19871221:20090401:20471221:SSK:7000:7700
000002:Mia:Sean:19800101:20090401:20500101:SK:3000:3210
000003:Mia:Boo:19641020:20090401:20241020:SK:7000:7490
000004:Mia:Nya:19921123:20090401:20521123:SSK:7000:7700
000005:Mia:Nya:19921123:20090405:20521123:SK:7000:7490
000006:Mia:Nya:20001010:20001210:20601010:SSK:400000:440000
000007:Mia:Nya:20051010:20061010:20651010:HSK:2000:2160
000008:Mia:Nya:19871221:20090401:20471221:SSK:5000:5500
000009:Mia:Nya:19800101:20090401:20500101:SK:3000:3210
000010:Mia:Miki:19871221:20090401:20471221:SSK:7000:7700
000011:Mia:Miki:19871221:20090401:20471221:SSK:7000:7700
000012:Mia:Miki:19800101:20090401:20500101:SK:7000:7490
000013:Mia:Miki:20001010:20041010:20601010:HSK:7000:7560
000014:Mia:Miki:19800101:19801011:20500101:SK:70000:74900

Result:

000001 Mia Miki 19871221 20090401 20471221 SSK 7000   7700
000002 Mia Sean 19800101 20090401 20500101 SK  3000   3210
000003 Mia Boo  19641020 20090401 20241020 SK  7000   7490
000004 Mia Nya  19921123 20090401 20521123 SSK 7000   7700
000005 Mia Nya  19921123 20090405 20521123 SK  7000   7490
000006 Mia Nya  20001010 20001210 20601010 SSK 400000 440000
000007 Mia Nya  20051010 20061010 20651010 HSK 2000   2160
000008 Mia Nya  19871221 20090401 20471221 SSK 5000   5500
000009 Mia Nya  19800101 20090401 20500101 SK  3000   3210
000010 Mia Miki 19871221 20090401 20471221 SSK 7000   7700
000011 Mia Miki 19871221 20090401 20471221 SSK 7000   7700
000012 Mia Miki 19800101 20090401 20500101 SK  7000   7490
000013 Mia Miki 20001010 20041010 20601010 HSK 7000   7560
000014 Mia Miki 19800101 19801011 20500101 SK  70000  74900

My code seems not good that it takes too much time to process.
Please help me to make it better.

I'm very new to shell scripting and trying to learn. If possible, please explain the meaning of the code.

I'm sorry for my bad English.

Any help is much appreciated.

** Edit: I feel stupid. Someone told me that I just need to simply use the "column -t" to accomplish this task. Thank you if anyone wanted to help me, and sorry for being stupid. :smiley:

this should work fast..

no=`awk -F":" -v l=\`awk 'END{print NR}' filename\` '
{A[NR]=length($1)" "length($2)" "length($3)" "length($4)" "length($5)" "length($6)" "length($7)" "length($8)" "length($9)}
END{for(i=0;i<l;++i)
{split(A,B," ");
{if(B[1]>max1){max1=B[1]}}
{if(B[2]>max2){max2=B[2]}}
{if(B[3]>max3){max3=B[3]}}
{if(B[4]>max4){max4=B[4]}}
{if(B[5]>max5){max5=B[5]}}
{if(B[6]>max6){max6=B[6]}}
{if(B[7]>max7){max7=B[7]}}
{if(B[8]>max8){max8=B[8]}}
{if(B[9]>max9){max9=B[9]}}
}{print max1" "max2" "max3" "max4" "max5" "max6" "max7" "max8" "max9}}' filename`
awk -F":" -v var="$no" '{split(var,A," ")}{printf "%-"A[1]"s %-"A[2]"s %-"A[3]"s %-"A[4]"s %-"A[5]"s %-"A[6]"s %-"A[7]"s %-"A[8]"s %-"A[9]"s\n",$1,$2,$3,$4,$5,$6,$7,$8,$9}' filename

Thanks for responding! :smiley:

Actually I need it to be more general, I mean not just to be running on 9 columns, but any given number of columns. But anyways I have learned something nice in your code. Thanks a lot! :smiley: