Đây là một kịch bản bash. Nó không sử dụng 'cột -t` và bộ tách biệt được xử lý chính xác như IFS, vì đó là IFS (hoặc ít nhất, phiên bản nội bộ của IFS của awk) ... Dấu phân cách mặc định là $' \ t '
Kịch bản này hoàn toàn đệm ra trường ngoài cùng bên phải.
'cột' không làm điều này.
Bằng cách đệm tất cả các cột, tập lệnh này có thể
dễ dàng sửa đổi để tạo khung bảng.
Ghi chú. Tệp đầu vào cần được xử lý hai lần
('cột' cũng cần thực hiện việc này)
Vượt qua đầu tiên là lấy chiều rộng tối đa của cột.
Vượt qua thứ hai là để mở rộng các trường (trên mỗi cột)
Đã thêm một số tùy chọn và sửa lỗi phát sáng (đổi tên biến :(
- -l Khoảng trắng bên trái của bất kỳ trường thụt lề nào
- -r Cắt khoảng trắng bên phải rộng hơn văn bản rộng nhất (đối với cột)
- -b Cả -l và -r
- -L Dấu phân tách đầu ra bên trái được thêm vào
- -R Dấu phân cách đầu ra phải được thêm vào
- -B Cả -L và -R
- -S Chọn bộ tách đầu ra
#!/bin/bash
#
# script [-F sep] [file]
#
# If file is not specified, stdin is read
#
# ARGS ######################################################################
l=;r=;L=;R=;O=;F=' ' # defaults
for ((i=1;i<=${#@};i++)) ;do
case "$1" in
-- ) shift 1;((i--));break ;;
-l ) l="-l";shift 1;((i-=1)) ;; # left strip whitespace
-r ) r="-r";shift 1;((i-=1)) ;; # right strip whitespace
-b ) l="-l";r="-r";shift 1;((i-=1)) ;; # strip both -l and -r whitespace
-L ) L="-L";shift 1;((i-=1)) ;; # Left output delimiter is added
-R ) R="-R";shift 1;((i-=1)) ;; # Right output delimiter is added
-B ) L="-L";R="-R";shift 1;((i-=1)) ;; # output Both -L and -R delimiters
-F ) F="$2";shift 2;((i-=2)) ;; # source separator
-O ) O="$2";shift 2;((i-=2)) ;; # output separator. Default = 1st char of -F
-* ) echo "ERROR: invalid option: $1" 1>&2; exit 1 ;;
* ) break ;;
esac
done
#
if [[ -z "$1" ]] ;then # no filename, so read stdin
f="$(mktemp)"
ifs="$IFS"; IFS=$'\n'; set -f # Disable pathname expansion (globbing)
while read -r line; do
printf "%s\n" "$line" >>"$f"
done
IFS="$ifs"; set +f # re-enable pathname expansion (globbing)
else
f="$1"
fi
[[ -f "$f" ]] || { echo "ERROR: Input file NOT found:" ;echo "$f" ;exit 2 ; }
[[ -z "$F" ]] && F=' ' # input Field Separator string
[[ -z "$O" ]] && O="$F" # output Field Separator
O="${O:0:1}" # use single char only
# MAIN ######################################################################
max="$( # get max length of each field/column, and output them
awk -vl="$l" -vr="$r" -vL="$L" -vR="$R" -vF="$F" -vO="$O" '
BEGIN { if (F!="") FS=F }
{ for (i=1;i<=NF;i++) {
if (l=="-l") { sub("^[ \t]*","",$i) }
if (r=="-r") { sub("[ \t]*$","",$i) }
len=length($i); if (len>max[i]) { max[i]=len }
if (i>imax) { imax=i }
}
}
END { for(i=1;i<=imax;i++) { printf("%s ",max[i]) } }
' "$f"
)"
awk -vl="$l" -vr="$r" -vL="$L" -vR="$R" -vF="$F" -vO="$O" -v_max="$max" '
BEGIN { if (F!="") FS=F; cols=split(_max,max," ") }
{ # Bring each field up to max len and output with delimiter
printf("%s",L=="-L"?O:"")
for(i=1;i<=cols;i++) { if (l=="-l") { sub("^[ \t]*","",$i) }
if (r=="-r") { sub("[ \t]*$","",$i) }
printf("%s%"(max[i]-length($i))"s%s",$i,"",i==cols?"":O)
}
printf("%s\n",R=="-R"?O:"")
}
' "$f"
# END #######################################################################
if [[ -z "$1" ]] ;then # no filename, so stdin was used
rm "$f" # delete temp file
fi
exit