tom*_*afe 8 unix bash escaping multiple-columns
我有一个制表符分隔的文本文件,我发送column到"漂亮的打印"表.
原始档案:
1<TAB>blablablabla<TAB>aaaa bbb ccc
2<TAB>blabla<TAB>xxxxxx
34<TAB>okokokok<TAB>zzz yyy
Run Code Online (Sandbox Code Playgroud)
使用column -s$'\t' -t <original file>,我明白了
1 blablablabla aaaa bbb xxx
2 blabla xxxxxx
34 okokokok zzz yyy
Run Code Online (Sandbox Code Playgroud)
如预期的.现在我想为列添加颜色.我试图在原始文件中的每个制表符分隔字段周围添加转义码.column成功打印颜色,但列不再对齐.相反,它只是逐字打印TAB分隔符.
问题是:如何使列对齐,还有独特的颜色?
我想过两种方法来实现这个目标:
column参数以使对齐与颜色代码一起使用问题是,我不确定如何做到这两个...
作为参考,这是我要传递的内容column:

请注意,这些字段确实由TAB字符分隔.我已经证实了这一点od.
编辑:
着色似乎没有问题.我已经有上面显示的文件,颜色代码正常工作.column一旦我使用转义码发送输入,问题就不会对齐.我正在考虑将没有颜色代码的字段传递给column,然后复制column每个字段之间输出的确切空格数,并在漂亮的打印方案中使用它.
我将用于awk着色(sed也可以使用):
awk '{printf "\033[1;32m%s\t\033[00m\033[1;33m%s\t\033[00m\033[1;34m%s\033[00m\n", $1, $2, $3;}' a.txt
Run Code Online (Sandbox Code Playgroud)
并将其通过column管道进行对齐:
... | column -s$'\t' -t
Run Code Online (Sandbox Code Playgroud)
输出:

小智 5
我写了一个bash版本的列(类似于util-linux的列),它使用了颜色代码:
#!/bin/bash
which sed >> /dev/null || exit 1
version=1.0b
editor="Norman Geist"
last="04 Jul 2016"
# NOTE: Brilliant pipeable tool to format input text into a table by
# NOTE: an configurable seperation string, similar to column
# NOTE: from util-linux, but we are smart enough to ignore
# NOTE: ANSI escape codes in our column width computation
# NOTE: means we handle colors properly ;-)
# BUG : none
addspace=1
seperator=$(echo -e " ")
columnW=()
columnT=()
while getopts "s:hp:v" opt; do
case $opt in
s ) seperator=$OPTARG;;
p ) addspace=$OPTARG;;
v ) echo "Version $version last edited by $editor ($last)"; exit 0;;
h ) echo "column2 [-s seperator] [-p padding] [-v]"; exit 0;;
* ) echo "Unknow comandline switch \"$opt\""; exit 1
esac
done
shift $(($OPTIND-1))
if [ ${#seperator} -lt 1 ]; then
echo "Error) Please enter valid seperation string!"
exit 1
fi
if [ ${#addspace} -lt 1 ]; then
echo "Error) Please enter number of addional padding spaces!"
exit 1
fi
#args: string
function trimANSI()
{
TRIM=$1
TRIM=$(sed 's/\x1b\[[0-9;]*m//g' <<< $TRIM); #trim color codes
TRIM=$(sed 's/\x1b(B//g' <<< $TRIM); #trim sgr0 directive
echo $TRIM
}
#args: len
function pad()
{
for ((i=0; i<$1; i++))
do
echo -n " "
done
}
#read and measure cols
while read ROW
do
while IFS=$seperator read -ra COLS; do
ITEMC=0
for ITEM in "${COLS[@]}"; do
SITEM=$(trimANSI "$ITEM"); #quotes matter O_o
[ ${#columnW[$ITEMC]} -gt 0 ] || columnW[$ITEMC]=0
[ ${columnW[$ITEMC]} -lt ${#SITEM} ] && columnW[$ITEMC]=${#SITEM}
((ITEMC++))
done
columnT[${#columnT[@]}]="$ROW"
done <<< "$ROW"
done
#print formatted output
for ROW in "${columnT[@]}"
do
while IFS=$seperator read -ra COLS; do
ITEMC=0
for ITEM in "${COLS[@]}"; do
WIDTH=$(( ${columnW[$ITEMC]} + $addspace ))
SITEM=$(trimANSI "$ITEM"); #quotes matter O_o
PAD=$(($WIDTH-${#SITEM}))
if [ $ITEMC -ne 0 ]; then
pad $PAD
fi
echo -n "$ITEM"
if [ $ITEMC -eq 0 ]; then
pad $PAD
fi
((ITEMC++))
done
done <<< "$ROW"
echo ""
done
Run Code Online (Sandbox Code Playgroud)
用法示例:
bold=$(tput bold)
normal=$(tput sgr0)
green=$(tput setaf 2)
column2 -s § << END
${bold}First Name§Last Name§City${normal}
${green}John§Wick${normal}§New York
${green}Max§Pattern${normal}§Denver
END
Run Code Online (Sandbox Code Playgroud)
输出示例:
