Aligning output with null fields in shell script

Hello Gurus !

I have what probably amounts to a few simply changes to fix; however for the life of me I cannot seem to get it ti work. I need to align the output of my script (I am writing to a logfile)... here's the lines in my code:

    if [ $header = "YES" ]
    then
        echo "NODE: $node" >> $logfile

        echo " " >> $logfile
        echo "Rule   Permission                                                                            Search" >> $logfile
        echo " ID       value    Owner     Group     Location                         File                  type" >> $logfile
        echo "------------------------------------------------------------------------------------------------------------------------------------" >> $logfile
        header="NO"
    fi
    printf "%-10s%-7s%-8s%-8s%-10s%-34s%-10s\n" "$id" "$permval" "$owner" "$group" "$loc" "$file" "$stype">> $logfile

My output looks like this:

NODE: bat
 
Rule   Permission                                                                            Search
 ID       value    Owner     Group     Location                         File                  type 
-----------------------------------------------------------------------------------------------------
1         755                    /                                                     ALL
3         755    testownertestgroup/         bat00043.bat                           FILE
10        755                    /uscripts                                            ALL

When it should look like this:

NODE: bat
 
Rule   Permission                                                                            Search
 ID       value    Owner     Group     Location                         File                  type 
-----------------------------------------------------------------------------------------------------
1         755                          /                                                      ALL
3         755      testowner testgroup /                                bat00043.bat          FILE
10        755                          /uscripts                                              ALL

Some things to note are that $owner, $group and $file may be NULL all other fields will have values. I think this is what is causing the issue. Is there wa way to tell unix (via printf, awk, sed or combination) to print a variable at a specific column regardless of it being NULL and it will not disturb other fields?

Thanks in advance to all that help out ... regards

Your data is larger than the field widths you have in the printf - testowner is 9, for instance, and you have %-8s .

This is "spacing" .. you have to take in consideration the previous field; do you not? But regardless; I tried it with longer lengths and it still doe not align.

Thanks

Not when the previous field isn't the problem. 8 characters is not spacing for a 9 character string - particularly when that column header is more like 11 characters (depending exactly how you want them to line up).

$ cat x.sh
#!/bin/bash

id=( "1" "3" "10" )
permval=( "755" "755" "755" )
owner[1]="testowner"
group[1]="testgroup"
loc=( "/" "/" "/uscripts" )

echo "Rule   Permission"
echo " ID       value    Owner     Group     Location"
echo "---------1---------2---------3---------4--------"
echo "1234567890123456789012345678901234567890--------"

for index in  0 1 2
do
   printf "%-10s%-7s%-11s%-11s%-10s\n" "${id[index]}" "${permval[index]}" "${own
er[index]}" "${group[index]}" "${loc[index]}"
done

$ ./x.sh
Rule   Permission
 ID       value    Owner     Group     Location
---------1---------2---------3---------4--------
1234567890123456789012345678901234567890--------
1         755                          /
3         755    testowner  testgroup  /
10        755                          /uscripts

Try this format:

printf "%-10s%-9s%-10s%-10s%-33s%-22s%-7s\n" "$id" "$permval" "$owner" "$group" "$loc" "$file" "$stype" >> $logfile

As mentioned above, the field width of some of the conversion specifiers in your printf format string aren't wide enough to accomdate the data. You have a decision to make: Do you want to truncate the values or not?

If you want to truncate, add precision to the specifier. %-8s creates an 8 character-wide field, but if the value is wider it will still be printed in its entirety, shifting following fields as necessary. Adding precision prevents this with truncation: %-8.8s . Note that the precision does not have to equal the field width. For example, %-8.5s represents a left-justified, 8 character-wide field whose string value will never exceed 5 characters.

If you do not want to truncate, then you have two choices. You can increase field widths until they are no longer likely to be a problem; or you can read all of the data first, determine the width of the widest value in each field, and then build the printf format string accordingly.

Regards,
Alister

1 Like

Thanks to everyone for looking at my problem; I think now I know what I will need to do.

Regards
G