2

I have an output file created from a Korn shell script. I need to align the output with spaces evenly. Unfortunately column -t is not available on AIX.

Actual File:

     X1vir1000      x1-DFB127   x1ttcb101_mv_03_2016   Not-activated  16         x1ttcr181   x1ttcr182
    X1vir1000       x1-DFB127   x1dvdb201_mv_pmp-132   Not-activated  3          x1ttcr181   x1ttcr182
    X3vir1000       x3-DFB116   x3dvdb202_mv_05032016   Not-activated  22         x3ttcr175   x3ttcr176
    X3vir1000       x3-DFB116   x3ttcb203_mv_03_2016   Not-activated  19         x3ttcr175   x3ttcr176
    X3vir1000       x3-DFB116   x3trcb223_mv_10_2017   Not-activated  29         x3ttcr175   x3ttcr176
    X3vir1000       x3-DFB117   x3trvf245_mv_08_2017   Not-activated  27         x3ttcr177   x3ttcr178
    X3vir1000      x3-DFB131   CR74536_x3dvap234_Decom   Not-activated  101        x3ttcr213   x3ttcr214
    X3vir1000      x3-DFB132   decommissioned_x3trcb223   Not-activated  138        x3ttcr217   x3ttcr218
    X3vir1000      x3-DFB132   decommissioned_x3trcb312   Not-activated  116        x3ttcr217   x3ttcr218
    X9vir1000       x9-DFB005-8233-E8B-SN1030BDR x9trcb003_vhost1_decomm   Not-activated  4          x9ttcr012   x9ttcr013


Expected Result: 


    X1vir1000   x1-DFB127                       x1ttcb101_mv_03_2016       Not-activated  16         x1ttcr181   x1ttcr182
    X1vir1000   x1-DFB127                       x1dvdb201_mv_pmp-132       Not-activated  3          x1ttcr181   x1ttcr182
    X3vir1000   x3-DFB116                       x3dvdb202_mv_05032016      Not-activated  22         x3ttcr175   x3ttcr176
    X3vir1000   x3-DFB116                       x3ttcb203_mv_03_2016       Not-activated  19         x3ttcr175   x3ttcr176
    X3vir1000   x3-DFB116                       x3trcb223_mv_10_2017       Not-activated  29         x3ttcr175   x3ttcr176
    X3vir1000   x3-DFB117                       x3trvf245_mv_08_2017       Not-activated  27         x3ttcr177   x3ttcr178
    X3vir1000   x3-DFB131                       CR74536_x3dvap234_Decom    Not-activated  101        x3ttcr213   x3ttcr214
    X3vir1000   x3-DFB132                       decommissioned_x3trcb223   Not-activated  138        x3ttcr217   x3ttcr218
    X3vir1000   x3-DFB132                       decommissioned_x3trcb312   Not-activated  116        x3ttcr217   x3ttcr218
    X9vir1000   x9-DFB005-8233-E8B-SN1030BDR    x9trcb003_vhost1_decomm    Not-activated  4          x9ttcr012   x9ttcr013
Kusalananda
  • 333,661

1 Answers1

2
FNR == NR {
    for (i = 1; i <= NF; ++i) {
        width = length($i)
        maxwidth[i] = (width > maxwidth[i] ? width : maxwidth[i])
    }

    next
}

{
    for (i = 1; i <= NF; ++i)
        printf("%-*s%s", maxwidth[i], $i,
            (i == NF ? "\n" : (delim == "" ? " " : delim)) )
}

This awk script expects to read the same file twice. The first time, it records the maximum width of each column in the input data. The second time, it prints the columns formatted to that maximum width.

If the delim variable is set, it is used to delimit the columns, otherwise a space character is used.

The default is to assume that the original data is whitespace-delimited. If it is tab-delimited, use -F '\t' on the command line.

Two test runs on the given data (note that the input file has to be specified twice):

$ awk -f ./script.awk file file
X1vir1000 x1-DFB127                    x1ttcb101_mv_03_2016     Not-activated 16  x1ttcr181 x1ttcr182
X1vir1000 x1-DFB127                    x1dvdb201_mv_pmp-132     Not-activated 3   x1ttcr181 x1ttcr182
X3vir1000 x3-DFB116                    x3dvdb202_mv_05032016    Not-activated 22  x3ttcr175 x3ttcr176
X3vir1000 x3-DFB116                    x3ttcb203_mv_03_2016     Not-activated 19  x3ttcr175 x3ttcr176
X3vir1000 x3-DFB116                    x3trcb223_mv_10_2017     Not-activated 29  x3ttcr175 x3ttcr176
X3vir1000 x3-DFB117                    x3trvf245_mv_08_2017     Not-activated 27  x3ttcr177 x3ttcr178
X3vir1000 x3-DFB131                    CR74536_x3dvap234_Decom  Not-activated 101 x3ttcr213 x3ttcr214
X3vir1000 x3-DFB132                    decommissioned_x3trcb223 Not-activated 138 x3ttcr217 x3ttcr218
X3vir1000 x3-DFB132                    decommissioned_x3trcb312 Not-activated 116 x3ttcr217 x3ttcr218
X9vir1000 x9-DFB005-8233-E8B-SN1030BDR x9trcb003_vhost1_decomm  Not-activated 4   x9ttcr012 x9ttcr013
$ awk -v delim=' | ' -f ./script.awk file file
X1vir1000 | x1-DFB127                    | x1ttcb101_mv_03_2016     | Not-activated | 16  | x1ttcr181 | x1ttcr182
X1vir1000 | x1-DFB127                    | x1dvdb201_mv_pmp-132     | Not-activated | 3   | x1ttcr181 | x1ttcr182
X3vir1000 | x3-DFB116                    | x3dvdb202_mv_05032016    | Not-activated | 22  | x3ttcr175 | x3ttcr176
X3vir1000 | x3-DFB116                    | x3ttcb203_mv_03_2016     | Not-activated | 19  | x3ttcr175 | x3ttcr176
X3vir1000 | x3-DFB116                    | x3trcb223_mv_10_2017     | Not-activated | 29  | x3ttcr175 | x3ttcr176
X3vir1000 | x3-DFB117                    | x3trvf245_mv_08_2017     | Not-activated | 27  | x3ttcr177 | x3ttcr178
X3vir1000 | x3-DFB131                    | CR74536_x3dvap234_Decom  | Not-activated | 101 | x3ttcr213 | x3ttcr214
X3vir1000 | x3-DFB132                    | decommissioned_x3trcb223 | Not-activated | 138 | x3ttcr217 | x3ttcr218
X3vir1000 | x3-DFB132                    | decommissioned_x3trcb312 | Not-activated | 116 | x3ttcr217 | x3ttcr218
X9vir1000 | x9-DFB005-8233-E8B-SN1030BDR | x9trcb003_vhost1_decomm  | Not-activated | 4   | x9ttcr012 | x9ttcr013

A shell script that embeds the above awk program and takes two options:

  • -d delim where delim is the output delimiter to use.
  • -D delim where delim is the input delimiter to use (e.g. -D '\t' for tabs in the input data).

The script would be use like this to recreate the two runs above:

./script.sh file
./script.sh -d ' | ' file

The script:

#!/bin/sh

while getopts 'd:D:' opt; do
    case $opt in
        d)  delim=$OPTARG ;;
        D)  fs=$OPTARG ;;
        *)  echo 'Error in command line parsing' >&2
            exit 1
    esac
done
shift "$(( OPTIND - 1 ))"

tmpfile=$(mktemp)
# If mktemp is not available:
# tmpfile="${TMPDIR:-/tmp}/columnn-t.tmp"
# ... or something similar
cat "$1" >$tmpfile

awk ${delim:+-v delim="$delim"} ${fs:+-F "$fs"} '
FNR == NR {
    for (i = 1; i <= NF; ++i) {
        width = length($i)
        maxwidth[i] = (width > maxwidth[i] ? width : maxwidth[i])
    }

    next
}

{
    for (i = 1; i <= NF; ++i)
        printf("%-*s%s", maxwidth[i], $i,
            (i == NF ? "\n" : (delim == "" ? " " : delim)) )    
}' "$tmpfile" "$tmpfile"

rm -f "$tmpfile"
Kusalananda
  • 333,661