漂亮的打印列中的颜色转义码 [英] Color escape codes in pretty printed columns
问题描述
我有一个制表符分隔的文本文件,该文件发送到column
来漂亮地打印"一张表.
I have a tab-delimited text file which I send to column
to "pretty print" a table.
原始文件:
1<TAB>blablablabla<TAB>aaaa bbb ccc
2<TAB>blabla<TAB>xxxxxx
34<TAB>okokokok<TAB>zzz yyy
使用column -s$'\t' -t <original file>
,我得到
1 blablablabla aaaa bbb xxx
2 blabla xxxxxx
34 okokokok zzz yyy
根据需要.现在,我想为列添加颜色.我试图在原始文件中每个制表符分隔的字段周围添加转义代码. column
成功以彩色打印,但各列不再对齐.相反,它只是逐字打印TAB分隔符.
as desired. Now I want to add colors to the columns. I tried to add the escape codes around each tab-delimited field in the original file. column
successfully prints in color, but the columns are no longer aligned. Instead, it just prints the TAB separators verbatim.
问题是:如何使列对齐,但颜色也要唯一?
The question is: how can I get the columns aligned, but also with unique colors?
我想到了两种方法来实现这一目标:
I've thought of two ways to achieve this:
- 调整
column
参数以使对齐方式与颜色代码一起使用 - 将列的输出重定向到另一个文件,并对前两个用空格分隔的字段进行搜索+替换(保证前两列不包含空格;最有可能的第三列将包含空格,但不包含TAB字符)
- Adjust the
column
parameters to make the alignment work with color codes - Redirect the output of column to another file, and do a search+replace on the first two whitespace-delimited fields (the first two columns are guaranteed to not contain spaces; the third column most likely will contain spaces, but no TAB characters)
问题是,我不确定该怎么做...
Problem is, I'm not sure how to do either of those two...
作为参考,这是我要传递给column
的内容:
For reference, here is what I'm passing to column
:
请注意,这些字段确实由TAB字符分隔.我已经通过od
确认了这一点.
Note that the fields are indeed separated by TAB characters. I've confirmed this with od
.
着色似乎没有问题.我已经有了上面显示的文件,并且颜色代码正常工作.问题是column
在我发送带有转义码的输入后将无法对齐.我正在考虑将没有 颜色代码的字段传递给column
,然后在每个字段之间复制确切数量的空格column
输出,并在漂亮的打印方案中使用它.
There doesn't seem to be an issue with the colorization. I already have the file shown above with the color codes working. The issue is column
won't align once I send it input with escape codes. I am thinking of passing the fields without color codes to column
, then copying the exact number of spaces column
output between each field, and using that in a pretty print scheme.
推荐答案
我写了一个bash版本的列(类似于util-linux中的列),它使用了颜色代码:
I wrote a bash version of column (similar to the one from util-linux) which works with color codes:
#!/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
示例用法:
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
输出示例:
这篇关于漂亮的打印列中的颜色转义码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!