我在 tcsh 脚本中有一个句子列表,这些句子由 '\n' 分隔,并且内部可能有空格。我想以ls的风格显示它们,所以我做了“echo $list|column”。当没有使用颜色时效果很好。结果如下
然后我需要突出显示一些每次都会更改的项目(最新的 3 个选择)。我在想要突出显示的项目周围添加颜色序列(\e[33m 和 \e[0m),并将它们放入 $list 中。当我用“echo $list | column”显示它们时,颜色没问题,但文本未对齐,如下图所示。
请注意,我尝试过如果不使用 '|列',字符串在一列中正确显示,即使不是我想要的样式。
有解决问题的办法吗?
顺便说一句,我做了一些搜索,这似乎是专栏的一个错误。专栏有维护者吗?我应该在哪里报告问题?
注意:我读过列命令和颜色转义代码的问题在发帖之前。他的格式是固定的,而我的彩色项目是动态的。所以简单地使用 printf 或在列后添加颜色是行不通的
答案1
无法理解对输出进行着色的转义序列column
,它仅通过计算输入中的“可打印字符”来进行操作。例如,将文本变为绿色的序列 ( ^[[0;32m
) 包含六个可打印字符,并且将按此计数。
如果您想查看column
确定列宽时真正看到的内容,请尝试以下操作:
ls --color=always / | tr -dc '\n -~' | column -s '\n'
如果您不支持此选项,请替换ls --color=always /
为具有彩色输出的任何命令。ls
无法说服column
忽略这些转义序列,但您可以随后添加颜色。
to-list
假设您有一个如下所示的文件:
1: avifsc01
2: avifsh01_bg4dtva0f
3: avifsh01_bg5dtvz1f
4: bg2ctqz1
5: bg2dtva0
6: bg3cda0
7: bg3cda1
8: bg3cdpa0
9: bg3z1
10: bg4cdpa0f
11: bg4cdpz1f
12: bg4cdz1f
13: bg4cta0f
14: bg4ctpa0f
15: bg4ctpz1f
16: bg4ctz1f
17: bg4dtva0f
18: bg4dtvz1f
19: bg5ctpz1f
20: bg5ctz1f
21: bg5dtvz1f
22: bg6ctz1f
23: bgpk01
24: dsc
25: test
26: vpp01
27: vrdlib01
然后你就可以:
list=$(cat to-list)
假设您知道要为一些特定条目着色:
to_color='bg3cda0 bg4dtva0f bg6ctz1f'
column
您可以在对列表进行着色之前格式化列表:
printf '%s\n' "${list}" \
| column -s '\n' \
| sed "s@$( (printf '%s\\|' ${to_color}; echo) \
| sed 's@^@\\([0-9][0-9]*: \\(@' \
| sed 's@\\|$@\\)\\)@' \
)@$(printf '\033')[33m\1$(printf '\033')[0m@g"
只要您有某种方法来生成这两个变量(${list}
和${to_color}
),这些条目就可以动态生成。
结果:
答案2
着色序列会扰乱字符计数,column
因此您可以在分栏步骤之后添加颜色,如下所示:
set items2color = ( "bg3cda0" "bg4dtva0f" "bg6ctz1f" )
echo "$list" | column |\
perl -slpe '\
for my $c ( split /\s+/, $C ) {\
s/(?:(?<=^)|(?<=\t))\d+:\s+\Q$c\E(?=\t|$)/\e[31m$&\e[0m/;\
}\
' -- -C="$items2color"
您想要着色的特定项目被放置在选项中的命令行上-C
,但您可以更改任何名称,然后 Perl 可以通过 $C 变量使用该名称。由于它是一个以空格分隔的项目列表,因此我们将其拆分为空格,并将正则表达式应用于当前行。行尾的反斜杠是因为tcsh
你说它是tcsh
你正在操作的列表变量。
正则表达式
正则表达式的简要工作如下: 请注意,由于正则表达式没有附加到任何变量,这意味着它附加到 $_ 变量,在我们的例子中是当前行。
/
(?: # From where we are,
(?<=^) # we see the beginning of the current line to our left
| # OR
(?<=\t) # we see a TAB to our left
)
# We are the beginning of a digit
\d+: # followed by one or more digits, ending in a colon
\s+ # then atleast one whitespace
\Q$c\E # followed by the item to be colored. \Q...\E quote the $c should
# it comprise any characters which mean something to the regex.
(?= \t | $ ) # we see a TAB or the end of line to our right
/x;