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

Seb*_*ian 84 command-line shell cat columns

例如,我有一个文件(用 生成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
Run Code Online (Sandbox Code Playgroud)

我更喜欢这样的输出(这里我使用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
Run Code Online (Sandbox Code Playgroud)

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

Tho*_*hor 106

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

column -t foo
Run Code Online (Sandbox Code Playgroud)

输出:

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
Run Code Online (Sandbox Code Playgroud)

摘自column(1)我的系统:

column -t foo
Run Code Online (Sandbox Code Playgroud)

  • 如果某些字段包含空格,您可能需要添加 `-s $'\t'`(虽然在每个列的实现中都没有)。 (17认同)
  • 我用它作为`column -ts: /etc/passwd`。看起来很酷! (4认同)
  • @RakholiyaJenish `$'\t'` 表示制表符。新行是 `$'\n'` 等等。 (2认同)

Sté*_*las 13

几个选项:

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'
Run Code Online (Sandbox Code Playgroud)

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

使用 zsh:

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


nis*_*ama 5

一个问题column -ts$'\t'是它删除了空字段,因此它有效地从行的开头删除了制表符,并用一个制表符替换了两个或多个连续的制表符:

$ echo $'\tcol1\tcol2\tcol3\nrow1\taa\t1\t100\nrow2\t\t\t200'>test.tsv
$ tr \\t ,<test.tsv
,col1,col2,col3
row1,aa,1,100
row2,,,200
$ column -ts$'\t' test.tsv
col1  col2  col3
row1  aa    1     100
row2  200
Run Code Online (Sandbox Code Playgroud)

因此我改用这个gawk函数(它依赖于 macOS 上不支持的数组数组nawk/usr/bin/awk

$ tab(){ gawk '{if(NF>m)m=NF;for(i=1;i<=NF;i++){a[NR][i]=$i;l=length($i);if(l>b[i])b[i]=l}}END{for(h in a){for(i=1;i<=m;i++)printf(i==m?"%s\n":"%-"(b[i]+n)"s",a[h][i])}}' "${1+FS=$1}" "n=${2-1}";}
$ tab \\t<test.tsv
     col1 col2 col3
row1 aa   1    100
row2           200
Run Code Online (Sandbox Code Playgroud)

第二种选择是使用rs(这是 macOS 附带的 BSD 实用程序):

$ x=$(cat test.tsv);rs -c -z $(wc -l<<<"$x")<<<"$x"
      col1  col2  col3
row1  aa    1     100
row2              200
Run Code Online (Sandbox Code Playgroud)

在 中rs-c更改输入列分隔符并将-c输入列分隔符设置为制表符。-z将每列的宽度设置为该列最长条目的宽度,而不是使所有列具有相同的宽度。如果某些行的列数少于第一行,请添加-n添加空列的选项,以填充列数少于第一行的行。

第三种选择是使用csvtk

$ csvtk -t pretty test.tsv
       col1   col2   col3
----   ----   ----   ----
row1   aa     1      100
row2                 200
$ csvtk -t pretty -s' ' test.tsv|sed 2d
     col1 col2 col3
row1 aa   1    100
row2           200
Run Code Online (Sandbox Code Playgroud)

-t选项使用制表符作为字段分隔符,但它不会禁用双引号的 CSV 样式处理。但是-l( --lazy-quote) 允许在输入中包含未转义的双引号:

$ echo $'1"\t2\n3\t4'|csvtk -t pretty
[ERRO] parse error on line 1, column 2: bare " in non-quoted-field
$ echo $'1"\t2\n3\t4'|csvtk -tl pretty
1"   2
--   -
3    4
Run Code Online (Sandbox Code Playgroud)


Jon*_*Deg 5

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

$ 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
Run Code Online (Sandbox Code Playgroud)

有多种格式选项。例如,-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
Run Code Online (Sandbox Code Playgroud)

tsv-pretty 参考中提供了更多信息。