正则表达式

正则表达式

我在 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;

相关内容