AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / unix / 问题 / 489150
Accepted
Asu
Asu
Asked: 2018-12-16 08:10:04 +0800 CST2018-12-16 08:10:04 +0800 CST 2018-12-16 08:10:04 +0800 CST

如何在bash中打印由TAB分隔的字符串?

  • 772

我正在尝试打印由 TAB 分隔的两个字符串。我努力了:

echo -e 'foo\tbar'
printf '%s\t%s\n' foo bar

他们都打印:

foo     bar

两者之间的空格实际上是 5 个空格(根据在 Putty 中使用鼠标选择输出)。

我也尝试过在输入命令时使用 CTRL+V 并按 TAB,结果相同。

强制标签打印为标签的正确方法是什么,所以我可以选择输出并将其复制到其他地方,带有标签?

第二个问题:为什么 bash 将制表符扩展到空格?

更新:显然,这是腻子的问题: https ://superuser.com/questions/656838/how-to-make-putty-display-tabs-within-a-file-instead-of-changing-them-to -空格

bash putty
  • 3 3 个回答
  • 24292 Views

3 个回答

  • Voted
  1. ilkkachu
    2018-12-16T08:29:32+08:002018-12-16T08:29:32+08:00

    两者之间的空格实际上是 5 个空格。

    不,这不对。不在echoor的输出中printf。

    $ echo -e 'foo\tbar' | od -c
    0000000   f   o   o  \t   b   a   r  \n
    0000010
    

    强制标签打印为标签的正确方法是什么,所以我可以选择输出并将其复制到其他地方,带有标签?

    这是一个不同的问题。这与 shell 无关,而是与终端仿真器有关,它在输出时将制表符转换为空格。许多人,但并非所有人都这样做。

    将带有制表符的输出重定向到一个文件,然后从那里复制它,或者unexpand在输出上使用将空格转换为制表符可能会更容易。(虽然它也不知道制表符的开头是什么空格,并且如果可能的话,会将所有空格都转换为制表符。)这当然取决于您需要对输出做什么。

    • 17
  2. Best Answer
    JoL
    2018-12-16T09:57:03+08:002018-12-16T09:57:03+08:00

    就像 ilkkachu 所说,这不是 bash 的问题,而是终端仿真器将制表符转换为输出时的空格。

    检查不同的终端,putty、xterm 和 konsole 将制表符转换为空格,而 urxvt 和 gnome-terminal 不会。因此,另一种解决方案是切换终端。

    • 9
  3. Stéphane Chazelas
    2018-12-17T08:47:55+08:002018-12-17T08:47:55+08:00

    在printf '%s\t%s\n' foo bar,printf做输出foo<TAB>bar<LF>。

    f, o, b,a和r是单角图形字符。

    收到这些字符后,终端将显示相应的字形并将光标向右移动一列,除非它已经到达屏幕的右边缘(原始远程打字机中的纸张)),在这种情况下它可能会输入一行并返回到屏幕的左边缘(换行)或只是丢弃字符,具体取决于终端及其配置方式。

    <Tab>是<LF>两个控制字符。<LF>(又名换行符)是 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
    

    也就是说,ABC4 列间隙和D。

    如果您用鼠标在xtermor中选择它putty,它们将在选择中存储ABC4 个空格字符D,而不是abC<CR>AC<BS>B<Tab><Esc>[C<BS><BS>D。

    printf最终选择的是终端驱动程序和终端仿真器已发送但经过后处理的内容。

    对于其他类型的转换,请参阅<U+0065><U+0301>(e后跟一个组合的重音) 更改为<U+00E9>(é预组合形式) by xterm。

    或者echo abc最终ABC由终端驱动程序翻译,然后再发送到终端stty olcuc。

    现在,<Tab>, like<LF>是文本文件中有时会出现的少数控制字符之一(也在<CR>MSDOS 文本文件中,有时<FF>用于分页符)。

    <CR>因此,一些终端仿真器确实选择在可能的情况下将它们复制到复制粘贴缓冲区中以保留它们(通常情况并非如此<LF>)。

    例如,在基于 VTE 的终端(如gnome-terminal)中,您可能会看到,当您选择printf 'a\tb\n'空行上的输出时,gnome-terminal实际上存储a\tb在 X11 选择中,而不是a、7 个空格和b。

    但是对于 的输出printf 'a\t\bb\n',它存储a, 6 个空格和b, 并且对于printf 'a\r\tb\n', a, 7 个空格和b。

    在其他情况下,终端会尝试复制实际输入,例如当您在运行后选择两行时,printf 'a \nb\n'将保留不可见的尾随空格。或者选择两行时,当两条线在右边边缘包裹时不包括LF字符。

    现在,如果要将输出存储printf到 CLIPBOARDX11选择中,最好直接这样做:

    printf 'foo\tbar\n' | xclip -sel c
    

    请注意,当您将其粘贴到xterm或大多数其他终端中时,xterm实际上会将其替换为\n,\r因为这是xterm您按下时发送的字符Enter(终端驱动程序可能会将其翻译回\n)。

    • 6

相关问题

  • 从文本文件传递变量的奇怪问题

  • 虽然行读取保持转义空间?

  • 如何使用 PuTTY 通过 ssh 将本地文件传输到远程服务器?[复制]

  • `tee` 和 `bash` 进程替换顺序

  • 运行一个非常慢的脚本直到它成功

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    如何将 GPG 私钥和公钥导出到文件

    • 4 个回答
  • Marko Smith

    ssh 无法协商:“找不到匹配的密码”,正在拒绝 cbc

    • 4 个回答
  • Marko Smith

    我们如何运行存储在变量中的命令?

    • 5 个回答
  • Marko Smith

    如何配置 systemd-resolved 和 systemd-networkd 以使用本地 DNS 服务器来解析本地域和远程 DNS 服务器来解析远程域?

    • 3 个回答
  • Marko Smith

    如何卸载内核模块“nvidia-drm”?

    • 13 个回答
  • Marko Smith

    dist-upgrade 后 Kali Linux 中的 apt-get update 错误 [重复]

    • 2 个回答
  • Marko Smith

    如何从 systemctl 服务日志中查看最新的 x 行

    • 5 个回答
  • Marko Smith

    Nano - 跳转到文件末尾

    • 8 个回答
  • Marko Smith

    grub 错误:你需要先加载内核

    • 4 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Martin Hope
    rocky 如何将 GPG 私钥和公钥导出到文件 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Wong Jia Hau ssh-add 返回:“连接代理时出错:没有这样的文件或目录” 2018-08-24 23:28:13 +0800 CST
  • Martin Hope
    Evan Carroll systemctl 状态显示:“状态:降级” 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim 我们如何运行存储在变量中的命令? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S 为什么 /dev/null 是一个文件?为什么它的功能不作为一个简单的程序来实现? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 如何从 systemctl 服务日志中查看最新的 x 行 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - 跳转到文件末尾 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla 为什么真假这么大? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST
  • Martin Hope
    Bagas Sanjaya 为什么 Linux 使用 LF 作为换行符? 2017-12-20 05:48:21 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve