Shell-Script

不使用“column - t”均勻對齊列

  • November 29, 2018

我有一個從 Korn shell 腳本創建的輸出文件。我需要將輸出與空格均勻對齊。不幸column -t的是,在 AIX 上不可用。

實際文件:

    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
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)) )
}

awk腳本期望讀取同一個文件兩次。第一次,它記錄輸入數據中每列的最大寬度。第二次,它列印格式化為該最大寬度的列。

如果delim設置了變數,則使用它來分隔列,否則使用空格字元。

預設情況下假定原始數據是空格分隔的。如果它是製表符分隔的,-F '\t'請在命令行上使用。

對給定數據進行兩次測試(注意輸入文件必須指定兩次):

$ 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

嵌入上述awk程序並採用兩個選項的 shell 腳本:

  • -d delim``delim要使用的輸出分隔符在哪裡。
  • -D delim要使用的輸入分隔符在哪裡delim(例如-D '\t'輸入數據中的製表符)。

該腳本將像這樣用於重新創建上面的兩個執行:

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

劇本:

#!/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"

引用自:https://unix.stackexchange.com/questions/484390