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 中使用,我可以获得相同的功能(请参阅此问题)。有没有程序可以自动进行这种格式化?我不想tabs在cating 文件之前试验该值。
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)
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)
一个问题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)
另一个可以做到这一点的工具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 参考中提供了更多信息。