我正在运行 macOS 12.3.1
我在我的 .zshrc 中添加了几行,即。
export GREP_OPTIONS='--color=always'
export GREP_COLOR='1;35;40'
在此之后,当我将 grep 输出通过管道传输到 tr 时,它返回相同数量的行,但所有行都是空白的
例如:
grep ^.....$ /usr/share/dict/words | tr "[:lower:]" "[:upper:]"
返回 10230 个空行。
这是预期的吗?
要以颜色输出匹配,
grep
请在匹配前后写入着色转义序列。这些是对终端更改背景和/或前景色的指令。
重要的是要意识到它与文本一起出现在输出中。您看不到它,因为您的终端不会将它们显示为图形符号,而是将其理解为特殊说明。
转义序列以 ESC 字符(ASCII aka
\e
or中的 0x1b 字节(八进制中的 033)^[
)开头,然后是一些本身不必是控制字符的字符。您可以通过将输出传递到以下内容来显示这些字符:
(这里还包括各个字节的十六进制和八进制值)
或者(尽管非标准且模棱两可):
grep
您可以在输出中看到,在\e[01;31\e[K
比赛之前和比赛\e[m\e[K
之后都有一个。给定终端识别哪些转义序列以及如何随终端而变化。例如,对于 xterm,请参阅那里的规范。这些天以上的人相当普遍。
对于以 开头
\e[
和结尾的m
那个,终端将每个 -;
分隔的数字理解为不同的渲染属性,以应用于从现在开始编写的文本。例如1
粗体,31
将前景色设置为红色。\e[K
是告诉终端从光标到行尾清除屏幕的转义序列。所以终端实际上看到:
但所有
tr
看到的是那些 ESC,[
, ...m
以及它被要求音译的其他那些。特别是这里,它会音译
m
为M
,而改变颜色属性的转义序列会一起变成别的东西。要了解转义序列及其作用,而不是查看终端文档(例如上面提到的 xterm 的https://www.invisible-island.net/xterm/ctlseqs/ctlseqs.html),这有时很难要查找或不存在,您还可以查看数据库,该
terminfo
数据库记录了一些终端识别的转义序列,用于一些常见的操作。您可以使用以下命令为您的终端(由
$TERM
环境变量标识)手动查询该数据库infocmp
:对于这些操作(功能)的详细信息,您可以查看
terminfo(5)
手册页(man 5 terminfo
)。\e[M
(delete_line
) 删除一行,\e[<decimal>M
(parm_delete_line
) 删除<decimal>
行。因此,一旦音译为大写,您的着色序列就变成了行删除序列。您通常不想对彩色输出进行后处理,因为它们仅适用于终端。这就是为什么大多数支持着色的命令在其输出不进入终端时会禁用它。
对于 GNU
grep
,正如您已经发现的那样,您需要--color=auto
(或grep --color
)获得该行为。现在,如果您仍想查看颜色,则需要将颜色移至管道中的最后一个命令,即输出到终端的命令:
在这里使用
--colour=auto
,如果包含该命令的脚本将其输出重定向/后处理,则禁用着色。在这里,由于正则表达式匹配整行(
-x
上面的选项,这避免了在您的方法中使用^
和$
喜欢),您不妨将前景色切换为红色,然后清除属性:这里用于为您的终端
tput
查询terminfo
正确的序列,但由于大多数终端都这样做,所以喜欢grep
并硬编码这些序列:用于
[ -t 1 ]
检查标准输出(文件描述符 1)是否为终端。GREP_OPTIONS
我通过从更改--color=always
为修复它--color=auto
我想 tr 和 color coded text 不能很好地结合在一起