是否有一个简单的命令用于输出制表符分隔的列?

是否有一个简单的命令用于输出制表符分隔的列?

例如,我有一个文件(用 生成echo -e "var1\tvar2\t\var3\tvar4" > foo),输出为:

$ cat foo
case    elems   meshing nlsys
uniform 2350    0.076662        2.78
non-conformal   348     0.013332        0.55
scale   318     0.013333        0.44
smarter 504     0.016666        0.64
submodel        360     .009999 0.40
unstruct-quad   640     0.019999        0.80
unstruct-tri    1484    0.01    0.88

我更喜欢这样的输出(这里我使用vim:set tabstop=14):

case          elems         meshing       nlsys
uniform       2350          0.076662      2.78
non-conformal 348           0.013332      0.55
scale         318           0.013333      0.44
smarter       504           0.016666      0.64
submodel      360           .009999       0.40
unstruct-quad 640           0.019999      0.80
unstruct-tri  1484          0.01          0.88

cat如果我$ tabs=15在 bash 中使用,我可以获得相同的功能(请参阅此问题)。有没有一个程序可以自动进行这种格式化?我不想在读取文件tabs之前尝试该值。cat

答案1

我通常使用该column程序来实现此目的,它位于bsdmainutilsDebian 上的一个名为的包中:

column -t foo

输出:

case           elems  meshing   nlsys
uniform        2350   0.076662  2.78
non-conformal  348    0.013332  0.55
scale          318    0.013333  0.44
smarter        504    0.016666  0.64
submodel       360    .009999   0.40
unstruct-quad  640    0.019999  0.80
unstruct-tri   1484   0.01      0.88

摘自column(1)我的系统:

...

-t      Determine the number of columns the input contains and create a
        table.  Columns are delimited with whitespace, by default, or
        with the characters supplied using the -s option.  Useful for
        pretty-printing displays.

...

答案2

几种选择:

var1=uniform var2=2350 var3=0.076662 var4=2.78

printf '%-15s %-10s %-12s %s\n' \
  case elems messing nlsys \
  "$var1" "$var2" "$var3" "$var4"

printf '%s\t%s\t%s\t%s\n' \
  case elems messing nlsys \
  "$var1" "$var2" "$var3" "$var4" |
  expand -t 15,25,37

printf '%s\t%s\t%s\t%s\n' \
  case elems messing nlsys \
  "$var1" "$var2" "$var3" "$var4" |
  column -t -s $'\t'

column 是非标准命令,某些实现/版本不支持 -s 选项。它根据输入计算列的宽度,但这意味着只有在所有输入都输入后它才能开始显示。$'...'zsh 和 bash 中也有 ksh93 语法吗?

使用 zsh:

values=(
  case elems messing nlsys
  "$var1" "$var2" "$var3" "$var4"
)
print -arC4 -- "$values[@]"

答案3

另一个可以做到这一点的工具tsv-pretty来自eBay 的 TSV 实用程序(免责声明:我是作者)。它需要额外的步骤,在小数点上排列数字字段。例如:

$ tsv-pretty foo
case           elems   meshing  nlsys
uniform         2350  0.076662   2.78
non-conformal    348  0.013332   0.55
scale            318  0.013333   0.44
smarter          504  0.016666   0.64
submodel         360   .009999   0.40
unstruct-quad    640  0.019999   0.80
unstruct-tri    1484  0.01       0.88

有多种格式选项。例如,为-u标题添加下划线并-f以类似方式格式化字段中的浮点数以提高可读性:

$ tsv-pretty foo -f -u
case           elems   meshing  nlsys
----           -----   -------  -----
uniform         2350  0.076662   2.78
non-conformal    348  0.013332   0.55
scale            318  0.013333   0.44
smarter          504  0.016666   0.64
submodel         360  0.009999   0.40
unstruct-quad    640  0.019999   0.80
unstruct-tri    1484  0.010000   0.88

更多信息请访问tsv-漂亮参考

答案4

另一种快速但肮脏的方法是使用该tabs命令,该命令包含ncurses在大部分 *nix 系统中并已安装在其中。

就我个人而言,我喜欢这个解决方案,因为它非常快并且很容易获得大部分正确的结果。

基于 @sebastian 提供的制表符分隔文件示例:

赶紧跑:

tabs 1,20,35,50

具有 ncurses tabstop 设置的示例数据

完成后,最好将选项卡恢复为标准硬件默认值......

tabs -8

(是的,我认为将选项卡显式设置为 -8 很奇怪,但这是我从阅读中得到的最佳解决方案man tabs,这是我见过的每个终端上的硬件默认值)

为了构建更完整的解决方案,我可能会使用stty size检查终端宽度,并将可变长度字段的宽度计算为终端宽度的百分比,并以应用程序明智的方式截断长列。

相关内容