如何使用具有输入颜色的列?

如何使用具有输入颜色的列?

使用 tput 颜色似乎会干扰列的输出。为什么会发生这种情况,更重要的是有解决办法吗?

$ {
  echo "$(tput bold)foo$(tput sgr0)" "$(tput bold)bar$(tput sgr0)"
  echo bar foo
} | column -t
foo  bar
bar                     foo

我在 macos 和 ubuntu 20.04 上重现了这个问题,尽管它们似乎都使用 BSD 列

答案1

您可以通过管道cat -v查看该文件流的所有字符。column使用它们计算宽度:

^[[1mfoo^[(B^[[m ^[[1mbar^[(B^[[m
bar foo

正确的方法是将任何内容创建与任何格式分开(如 MVC 模型)。请注意,column添加空格以生成类似制表符的输出,因此它会修改内容。同时tput向终端添加指令。通过分离这些任务,我们能够将输出保存到文件中,或者从我们的格式化函数传递它以将其发送到控制台,或者将其格式化为其他目的地。


但这也是一个很好的练习awk,可以实现column -t从宽度计算中排除某些字符。我下面使用的正则表达式捕获了很多tput东西,但我几乎可以肯定不是全部。

$ cat tst.awk
BEGIN {
    OFS = "  "
}

{
    nr = NR
    for (i=1;i<=NF;i++) {
        f[NR,i] = $i
        gsub(/\x1B[^[:alpha:]]+[[:alpha:]]/,"",$i)
        if (length($i) > col[i]) col[i] = length($i)
    }
}

END {
    for (i=1;i<=nr;i++) {
        for (j=1;j<=length(col);j++) {
            printf "%-"col[j]"s%s", f[i,j], (j==length(col)? ORS : OFS)
        }
    }
}

然后将第一个输出通过管道传输到awk -f tst.awk

答案2

${
    echo -e "$(tput 粗体)foo$(tput sgr0)" "$(tput 粗体)bar$(tput sgr0) baz";
    回声酒吧富;
  } |cat -v
^[[1mfoo^[(B^[[m ^[[1mbar^[(B^[[m baz)
富酒吧

问题在于tput sgr0,正如您所知,默认情况下tputs使用基于从环境变量获取的终端类型的转义代码TERM

如果你这样做:

infocmp -1 |grep -E 'bold|sgr0'
    bold=\E[1m,
    sgr0=\E(B\E[m,

你会看到什么大胆的sgr0代码是(那些是非 ANSI 转义值),正如您在cat -v转换为^[[1mfortputs bold^[(B^[[mfor后的输出中看到的那样sgr0column命令执行相同的操作并解析为 ANSI 转义类型代码,但当存在(B并保留时会失败^[(B^[[m,然后就不会在 ANSI 转义中被识别并导致最终输出未按预期正确地按列输出。

如果你这样做:

infocmp -1 -T ansi |grep -E 'bold|sgr0'
        bold=\E[1m,
        sgr0=\E[0;10m,

您将找到每个等效的 ANSI 转义码;所以你有两个选择来解决它:

  1. 替换tputs为上面的 ANSI 转义码

    { 
      echo -e "\033[1mfoo\033[0;10m" "\033[1mbar\033[0;10m baz";
      echo bar foo;
    } |column -t
    
  2. 将终端类型传递给tputs

    {
      echo -e "$(tput bold)foo$(tput -T ansi sgr0)" "$(tput bold)bar$(tput -T ansi sgr0) baz";
      echo bar foo;
    } |column -t
    

答案3

column我正在运行 Ubuntu 18.04,并对未按预期运行的行为感到困惑。正如其他人所建议的,问题在于该仓库包含一件古董。

我发现获得现代版本的唯一方法是从util-linux回购协议

很难弄清楚这一点,因为-V尚未添加获取版本!可能有一种更优雅的方式,但我通过调用man column底部的日期“2004 年 7 月 29 日”来推断出大致的版本。比较2004 年联机帮助页2019 年联机帮助页。虽然前者仅描述选项,后者几乎有两打

我还可以说,在 MacOS Catalina 上我得到了完全相同的结果。我无法找到brew包含更新版本的软件包,column但它可能隐藏在某个地方。

如果您无法访问现代版本,您应该确保检查与现有版本相对应的手册页,否则事情会令人沮丧!

相关内容