在中printf '%s\t%s\n' foo bar,printf输出foo<TAB>bar<LF>。
f,o,b,a和r是单宽度的图形的字符。
接收到这些字符后,终端将显示相应的标志符号,并将光标向右移动一列,除非光标已到达屏幕的右边缘(原始远程打字机中为纸张),在这种情况下,它可能会换行然后返回到屏幕的左边缘(自动换行),或者根据终端及其配置方式放弃该字符。
<Tab>和<LF>是两个控制字符。<LF>(aka newline)是Unix文本中的行定界符,但对于终端,它仅输入一行(将光标向下移动一个位置)。因此内核中的终端驱动程序实际上会将其转换为<CR>(返回到屏幕的左边缘),<LF>(光标向下)(stty onlcr通常默认情况下为打开)。
<Tab> 告诉终端将光标移动到下一个制表位(默认情况下,大多数终端上的制表位相隔8个位置,但也可以配置为在任意位置设置),而不会用空格填充空白。
因此,如果将这些字符发送到终端,并且制表符每8列停住一次,而光标位于空行的开头,则会导致:
foo bar
打印在屏幕上的那一行。如果在光标位于包含的行中的第三位置时发送了它们xxxxyyyyzzzz,则会导致:
xxfooyyybarz
在不支持制表的终端上,可以将终端驱动程序配置为将这些选项卡转换为空格序列。(stty tab3)。
在原始的远程打字机中,SPC字符会将光标向右移动,而退格键(\b)将其向左移动。现在,在现代终端中,SPC会向右移动并擦除(按您的期望写入空格字符)。因此,的项\b必须比ASCII更新。在大多数现代终端,它实际上是一个字符序列:<Esc>,[,C。
还有更多的转义序列可将n字符向左,向右,向上,向下或屏幕上的任意位置移动。还有其他转义序列可擦除(填充空白)屏幕的部分行或区域等。
那些序列通常用于通过视觉应用程序,如vi,lynx,mutt,dialog其中文本在屏幕上的任意位置写入。
现在,所有X11终端仿真器和其他一些非X11终端仿真器(例如GNU)都screen使您可以选择屏幕区域以进行复制粘贴。在vi编辑器中选择一部分内容时,您不想复制用于生成该输出的所有转义序列。您想要选择在那里看到的文本。
例如,如果您运行:
printf 'abC\rAC\bB\t\e[C\b\bD\n'
它模拟了您在其中输入的编辑器会话abC,返回到开头,用替换ab为AC,C用B,移至下一个制表位,然后在右侧再增加一列,在左侧再增加两列,然后输入D。
你看:
ABC D
也就是说ABC,有4列的间隙和D。
如果用xterm或鼠标putty选择该选项ABC,它们将存储在选择项中,四个空格字符D,而不是abC<CR>AC<BS>B<Tab><Esc>[C<BS><BS>D。
选择的结果是printf终端驱动程序和终端仿真器已发送但已对其进行后处理的内容。
有关其他类型的转换,请参见将<U+0065><U+0301>(e紧随重音合并)由更改为<U+00E9>(é预组合形式)xterm。
或echo abc最终ABC由终端驱动程序转换为,然后发送给终端stty olcuc。
现在,<Tab>就像<LF>有时在文本文件中(有时<CR>在MSDOS文本文件中,有时是<FF>用于分页符)中发现的少数几个控制字符之一一样。
因此,一些终端模拟器不选择可能的情况下将它们复制在复制粘贴的缓冲区来保存它们(这通常不是的情况下<CR>,也不<LF>虽然)。
例如,在基于VTE的终端中,例如gnome-terminal,您可能会看到,当printf 'a\tb\n'在空行上选择输出时,gnome-terminal实际上存储a\tb在X11选择中,而不是a7个空格和b。
但是,对于输出printf 'a\t\bb\n',其存储a,6位和b,以及用于printf 'a\r\tb\n',a,7位和b。
在其他情况下,终端将尝试复制实际输入,例如在运行后选择两行时printf 'a \nb\n',将保留不可见的尾随空间。或者,当选择两行时,如果右行换行导致两行不包含LF字符。
现在,如果要将输出存储printf到CLIPBOARD X11select中,最好的做法是直接执行以下操作:
printf 'foo\tbar\n' | xclip -sel c
请注意,将其粘贴到xterm其他终端或大多数其他终端时,xterm实际上将其替换为\n,\r因为这是xterm您按下时发送的字符Enter(终端驱动程序可能会将其转换回\n)。