为什么单位分隔符 (ASCII 31) 在终端输出中不可见?

dan*_*dan 18 terminal ascii

单位分隔符 ASCII 字符(ASCII 31,八进制 37)在 Vim 中显示为^_. 但是如果我将相同的文件打印到终端,则该字符是不可见的。这会导致一行上的字段粘在一起:

# In Vim and less:

first field^_second field^_last field

# cat the same file to terminal:
cat delim.txt
first fieldsecond fieldlast field

# print 2nd field with awk 
cat delim.txt | awk 'BEGIN {FS = "\037"} {print $2}'
second field
Run Code Online (Sandbox Code Playgroud)

我想我可以使用 cat -v 使单位分隔符可见:

cat -v delim.txt
first field^_second field^_last field
Run Code Online (Sandbox Code Playgroud)

但这比较麻烦。为什么在 Bash shell 中打印到标准输出时,单位分隔符没有可见的表示?我什至无法正确复制和粘贴 shell 输出;单元分离器在此过程中丢失。

Mic*_*ler 20

单位分隔符 ( US) 字符,也称为IS1,属于cntrl字符类,属于print字符类。它是一个控制字符,用于将文本组织成组,用于旨在利用该信息的程序。一般来说,不可打印的字符可能会在不同的程序或环境中被不同地解释和呈现。

^_在 Vim中看到它的原因是因为 Vim 是一个交互式编辑器。只要将正确的二进制字符写入磁盘,它就可以随意渲染不可打印的字符。

您无法在 shell 中获得相同的行为,因为编写 Unix shell 程序是为了对彼此进行操作并将纯文本传递给彼此。当您cat创建文件时,写入终端的文本必须是文件中的实际内容。

这样就把它留给终端设备来解释字符。事实证明,某些终端仿真器确实US与其他仿真器不同的方式呈现角色。在gnome-terminal(或任何vte基于终端的)中,字符将呈现为包含十六进制代码的框001F。在xtermor 中rxvt,字符确实是不可见的。


cra*_*150 10

单位分隔符在Control Characters的 ASCII 范围内,因此没有(或通常不应该)具有可视化表示。

Vim 和其他一些编辑器会显示它们,因此您可以编辑它们。正如您所注意到的,也cat -v显示它。手册页显示,这-v是 的缩写形式--show-nonprinting,这导致它用可打印的表示替换非打印字符,这不是文件的原始内容,因此可能会导致问题,如果输出实际上是到另一个程序.

您看到的表示已经暗示它是一个控制字符:前面带有 a 的字符^Ctrl+ 字符的常用符号,它是在终端中生成此字符的组合键。Ctrl+_会让你在 vim 中输入单位分隔符,例如。但是另一个编辑器或某些 GUI 查看器可能会显示十六进制代码、占位符或完全不同的东西。

由于您的终端不打印控制字符,因此在选择文本时也不会复制它(换行符和制表符等空白字符在这里是个例外,它们也是控制字符)。复制时通常会忽略的终端中控制字符的另一个示例是颜色代码,它是一个ESC字符后跟用于为文本着色的代码。

因此,要在终端上显示字符,除了使用将单位分隔符替换为某些可打印字符的程序之外别无他法。