我的输入包含我想要表格化的 ANSI 颜色代码。我希望输出保持彩色,因此表格输出应保持 ANSI 颜色代码。因此,天真地剥离它们并不符合我的要求。
例如,对于此输入,
\033[0;32;1mgreen_apple\033[0m 1 100
orange 20 19
pineapple 1000 87
avocado 4 30
我期望的输出类似于
green_apple 1 100
orange 20 19
pineapple 1000 87
avocado 4 30
在上面的输出中,“green_apple”应根据输入的颜色代码(即绿色)进行着色。我想知道如何实现这一点。
我已经尝试过列,但它不处理 ANSI 代码。的输出
echo '\033[0;32;1mgreen_apple\033[0m 1 100
orange 20 19
pineapple 1000 87
avocado 4 30' | column -t
不幸的是
green_apple 1 100
orange 20 19
pineapple 1000 87
avocado 4 30
注意非表格化。
答案1
我认为没有这样的命令,你必须手动执行。就像是:
awk '
{
nf[NR]=NF
for (i = 1; i <= NF; i++) {
f[NR,i] = $i
gsub(/\033\[[0-9;]*[mK]/, "", $i)
len[NR,i] = l = length($i)
if (l > max[i]) max[i] = l
}
}
END {
for (n = 1; n <= NR; n++) {
for (i = 1; i < nf[n]; i++)
printf "%s%*s", f[n,i], max[i]+1-len[n,i], ""
print f[n,nf[n]]
}
}'
答案2
对于任何感兴趣的人,我改编了这个 awk 脚本斯特凡·查泽拉斯的回答。您应该能够将其放入您的计算机中$PATH
并从命令行运行它。
例如:
> echo -e '\e[32mHello\e[0m,World\nFoo,Bar' | colorcolumn FS=',' OFS=' | '
Hello | World
Foo | Bar
#!/usr/bin/awk -f
#
# colorcolumn - Like `column`, but works with ANSI colors
#
# Based on this Stack Exchange answer by Stephane Chazelas:
# https://unix.stackexchange.com/a/121139/259233
{
nf[NR]=NF
for (i = 1; i <= NF; i++) {
cell[NR,i] = $i
gsub(/\033\[([[:digit:]]+(;[[:digit:]]+)*)?[mK]/, "", $i)
len[NR,i] = l = length($i)
if (l > max[i]) max[i] = l
}
}
END {
for (row = 1; row <= NR; row++) {
for (col = 1; col < nf[row]; col++)
printf "%s%*s%s", cell[row,col], max[col]-len[row,col], "", OFS
print cell[row,nf[row]]
}
}
答案3
问题当然是column
不区分打印和非打印字符,通过其提示符 ( ) 及其转义功能bash
来解决这个问题,我不知道还有什么其他方法可以做到这一点。PS1
\[ \]
鉴于您的问题领域位于开始该行的,将其移至 then结尾,但是您会遇到类似的填充/对齐问题,而使用常见实用程序无法轻松解决这些问题。
ls -l --color | rev | column -t | rev # not a useful solution
如果你安装了 perlHTML::FromANSI
模块,它有一个有用的ansi2html
脚本:
ls -l --color | ansi2html -f
这只能让你成功一半,现在你必须对齐 HTML 输出......
有一个简单的(虽然稍微重量级的)解决方案,以 HTML 作为中间:HTML 表格的布局实际上就是您想要做的事情。
这使用安德烈·西蒙的抗过滤器,例如:
ls -l --color | ansifilter -fH
这会将 ANSI 序列转换为 HTML ( <span style="..."></span>
),然后可以使用支持文本模式 ANSI 的浏览器(例如电子链接。
如果 HTML 不完整是个问题,您可以选择运行hxclean
或者htmltidy
在将 HTML 传递到浏览器之前清理它。
ls -l --color | ansifilter -fH | perl table.pl | elinks -dump -dump-color-mode 1
你应该能够使用电子链接或者w3m 为了这
该table.pl
脚本按空格分割并添加相关的 HTML 表标签以实现所需的格式:
print "<table>\n";
while (<>) {
print "<tr><td>" .
join("</td><td>", split(/((?!<[^>]+)\s+(?![^<]+>))/) ) .
"</td></tr>\n";
}
print "</table>\n";
事实并非如此只是在任何空格上分割,它会在不在“<”“>”尖括号内的空格上分割,因此不会破坏标签<span>
。这不是解析 HTML 的好方法,但对于此处的约束输入类型来说应该足够了。
您可能需要(我确实)设置或覆盖默认颜色,或者将它们添加到您的~/.elinks/elinks.conf
文件中:
set document.colors.use_document_colors = 1
set document.colors.text = "#000000"
set document.colors.background = "#ffffff"
确保使用最新的 (0.12.x) elinks,早期版本不支持 ANSI 颜色输出。
答案4
假设水果名称仅包含_
和alphabetic
字符。
c='(\e|\\033)\[[0-9;]+m'
sed -r "s/^($c)?([a-zA-Z_]+)($c)?/& \3/" file | column -t |
sed -r "s/^($c[a-zA-Z_]+$c)( +)([a-zA-Z_]+)/\5\4\1/" |
sed -r "s/^[^ ]+ +//"
输出:
\033[0;32;1mgreen_apple\033[0m 1 100
orange 20 19
pineapple 1000 87
avocado 4 30
要(测试)以颜色显示输出,printf
只需管道通过shell命令替换,例如:
c='(\e|\\033)\[[0-9;]+m'; printf "$(
sed -r "s/^($c)?([a-zA-Z_]+)($c)?/& \3/;" file | column -t |
sed -r "s/^($c[a-zA-Z_]+$c)( +)([a-zA-Z_]+)/\5\4\1/" |
sed -r "s/^[^ ]+ +//" )"
带颜色输出 –仅有的 青苹果以颜色显示。
green_apple 1 100
orange 20 19
pineapple 1000 87
avocado 4 30