我想玩一下find -fprintf
。如果您不知道它的作用,它与写入您指定其名称的文件-fprintf
相同。-printf
现在,当我运行这样的命令时:
find -maxdepth 1 -type d -fprintf output "%p\b\n"
我得到以下内容output
(使用vim
几乎任何文本编辑器):
.^H
./directory-1^H
./directory-2^H
./directory-3^H
我知道这^H
是退格字符。开头output
:less
./directory-
./directory-
./directory-
所以,问题是:
- 为什么
vim
和其他文本编辑器(尝试过nano
和emacs
)会显示退格键而不通过删除其前面的字符来解释它,但less
会显示退格键? - 为什么编辑器不打印一个字符
\n
而不是换行呢? - 打印退格键和按下键盘上的退格键(按下键盘上的退格键实际上会删除一个字符)有什么区别?
我在我的机器(笔记本电脑)上运行它,而无需在任何地方进行 sshing。使用带有 konsole 和 tmux 的 GNU/Linux Ubuntu 16.04 LTS。
答案1
为什么 vim 和其他文本编辑器(尝试过 nano 和 emacs)显示退格键而不通过删除其前面的字符来解释它,但 less 却这样做?
他们为什么要这么做? FWIW,浏览器也没有:-)
$ printf "<html>foo\bbar</html>" > /tmp/foo.html
$ firefox /tmp/foo.html
编辑器是否还应该解释其他类型的标记,例如迷你 Markdown*foo*
或**bar**
?
请注意,退格键不仅仅是“删除”中的前一个字符less
,而且还用作粗略的格式化字符。将以粗体x\bx
打印,并在其下划线(在某些终端上会导致它以不同的颜色打印):x
x\b_
printf "H\b_e\b_r\b_e\b_'s\bs Johnny!" | less
为什么编辑器不打印 \n 字符而不是向下换行?
他们可以做到这一点。例如,如果您使用:set list
in vi
,则换行符将打印为$
,制表符将打印为^I
。
打印退格键和按键盘上的退格键(按键盘上的退格键实际上会删除字符)之间有什么区别?
在硬类型终端(在纸上打印)上,打印退格会导致笔架向左移动一个位置,因此后续的字符将覆盖,而不是删除纸上已有的内容。在玻璃 (CRT) 和模拟终端上,向左移动位置并写入字符会产生“擦除”效果,因为覆盖字符会完全替换它。但\b
本身并没有删除任何内容:printf "123\b\n"
will print 123
not 12
。
后者是 tty 驱动程序的一个功能,它将一些输入字符解释为编辑/控制命令(erase
、werase
、intr
、kill
-- 查看stty(1)
或termios(3)
手册页以获取完整列表)。
退格键也可以不是始终生成\b
/ ^H
(BS) 字符。大多数时候是\x7f
/ ^?
(DEL)。
但你可以将其设置为你喜欢的任何值:
$ stty erase '#'
现在点击#
将删除之前的字符,就像在 unix v7 中一样。
答案2
文件内容是由应用程序构成的。
Unix 设计的特点之一是文件是无区别的字节序列,并且由应用程序对其进行任何它们喜欢的解释。应用程序可以并且确实以不同的方式解释文件内容,并且您正在经历这样做的后果。
VIM 根据 Single Unix 规范的概念来解释文件内容文本文件,这是一个由零个或多个以字符结尾␊
且不包含任何␀
字符的行组成的文件。它将不可打印的字符转换为各种可打印的表示形式,但␊
始终是行尾,因为这是概念的一部分。
其他实用程序以不同方式解释文件内容。其中一个系列将文件内容解释为 Teletype Model 37 (TTY-37) 输出数据流。该系列包含几个传统的 Unix 和 GNU 程序:less
、more
、most
、ul
、colcrt
、ncal
、grotty
非默认模式等。在这种解释中,␈
角色将(概念上的)打印头移回一个位置并重击之前有什么。因为这些程序不是纸上有墨水的物理 TTY-37,所以它们在软件中实现了自己的想法,即重打的含义。过度打印可能会导致尝试使用粗体和下划线属性、将一个字符完全替换为另一个字符、组合字符或根本不替换任何字符。
进一步阅读
- ”文本文件”。 基本定义。单一 UNIX 规范。 IEEE 1003.1。 2018。公开组。
- 为什么“cal”使用奇怪的 08 / ^H / \b 终端代码来突出显示以及它是如何工作的?
- 乔纳森·德博因·波拉德 (2017)。改进的手册页
ul
。提案。