如何根据内容展开标签?

smo*_*ris 5 shell pipe text-processing

我有一些来自 Unix 管道的制表符分隔数据。我想将这些数据格式化为一个紧凑的人类可读表格。

如何将这些制表符展开为空格,并根据字段数据的宽度自动设置制表位?

例如,我的假设generate_tsv脚本可能会产生(我\t用来表示实际的制表符)-

alpha\t1\t0.21085026\tok
beta\t4096\t0.0\tok
gamma\t\t-1.0\tinvalid
Run Code Online (Sandbox Code Playgroud)

使用| expand -t 12,我会得到:

alpha       1           0.21085026  ok
beta        4096        0.0         ok
gamma                   -1.0        invalid
Run Code Online (Sandbox Code Playgroud)

但我想要更紧凑的东西(所以正好有两个空格分隔列),如下所示:

alpha  1     0.21085026  ok
beta   4096  0.0         ok
gamma        -1.0        invalid
Run Code Online (Sandbox Code Playgroud)

正如@jw013 所建议的那样,| column -t -s $'\t'很接近,但并不完全正确,因为它会折叠空单元格:

alpha  1     0.21085026  ok
beta   4096  0.0         ok
gamma  -1.0  invalid
Run Code Online (Sandbox Code Playgroud)

jw0*_*013 5

如果您有column(1)一个旧的 BSD 工具,请尝试column -t, 用于漂亮的打印表格。

为确保显示空单元格,您可以尝试在每个空单元格中插入一个空格(可通过两个连续选项卡识别)的方法。这个想法是column(1)应该给空格字符自己的列,但作为宽度的单个字符,它不应该影响表格尺寸或在输出中对人类可见。

generate_tsv | 
   awk '/\t\t/ { for (i = 0; i < 2; i++) gsub(/\t\t/, "\t \t") } 1' | 
   column -t -s $'\t'
Run Code Online (Sandbox Code Playgroud)

如上所述awk,管道中插入的额外内容会将空格插入到每个空单元格中。处理 2 个连续的空单元格 ( \t\t\t)需要 2 次传递。