我可以用来stat
创建一个 ls 输出,显示两种格式的权限信息,这很方便:
stat --printf="%A\t%a\t%h\t%U\t%G\t%s\t%.19y\t%n\n" . .*
drwxr-xr-x 755 4 boss boss 4096 2021-10-29 22:49:12 .
drwxr-xr-x 755 4 boss boss 4096 2021-10-29 22:49:12 .
drwxr-xr-x 755 36 boss boss 4096 2021-11-01 11:30:24 ..
-rw-r--r-- 644 1 boss boss 97708 2021-11-01 11:30:16 .custom
-rw-r--r-- 644 1 boss boss 4013 2021-10-11 22:04:04 .custom-dk
然而,列之间的间距\t
很好,但相当“间隙”。这让我很好奇,是否有一种通用方法可以对这样的任何输出进行后处理,使得列将处于单空间间隙的最低公分母,即是否有一种通用方法可以将上面的内容调整为类似于下面的内容使用awk
orsed
或类似的(如果可能的话,我也将数字列右对齐作为“理想”输出)?
drwxr-xr-x 755 4 boss boss 4096 2021-10-29 22:49:12 .
drwxr-xr-x 755 4 boss boss 4096 2021-10-29 22:49:12 .
drwxr-xr-x 755 36 boss boss 4096 2021-11-01 11:30:24 ..
-rw-r--r-- 644 1 boss boss 97708 2021-11-01 11:30:16 .custom
-rw-r--r-- 644 1 boss boss 4013 2021-10-11 22:04:04 .custom-dk
答案1
关于你的问题中的“或 sed” - sed 是用于对单个字符串进行简单 s/old/new/ 转换的正确工具,你所做的不是那样的,所以 sed 甚至不应该是一个选项考虑。
使用 2 遍方法,首先确定每列的最大宽度和对齐方式,然后在打印时使用它们,在每个 Unix 机器上的任何 shell 中使用任何 awk:
$ cat tst.awk
BEGIN { FS="\t" }
NR==FNR {
for (i=1; i<=NF; i++) {
align[i] = ( $i ~ /^[0-9]+$/ ? "" : "-" )
width[i] = ( length($i) > width[i] ? length($i) : width[i] )
}
next
}
{
for (i=1; i<NF; i++) {
printf "%" align[i] width[i] "s ", $i
}
print $NF
}
$ awk -f tst.awk file file
drwxr-xr-x 755 4 boss boss 4096 2021-10-29 22:49:12 .
drwxr-xr-x 755 4 boss boss 4096 2021-10-29 22:49:12 .
drwxr-xr-x 755 36 boss boss 4096 2021-11-01 11:30:24 ..
-rw-r--r-- 644 1 boss boss 97708 2021-11-01 11:30:16 .custom
-rw-r--r-- 644 1 boss boss 4013 2021-10-11 22:04:04 .custom-dk
上面假设您的最后一列始终是左对齐的,如果情况并非如此,请告诉我们,因为这两种方式都不难处理。它还假设列的对齐方式可以由输入的最后一行中的字段中的值(数字或非数字)确定。
如果输入必须来自管道而不是文件(因此您不能打开输入两次),那么您可以将输入存储在数组中并在 END 部分中打印:
$ cat tst.awk
BEGIN { FS = "\t" }
{
for (i=1; i<=NF; i++) {
width[i] = ( length($i) > width[i] ? length($i) : width[i] )
align[i] = ( $i ~ /^[0-9]+$/ ? "" : "-" )
vals[NR,i] = $i
}
}
END {
for (n=1; n<=NR; n++) {
for (i=1; i<NF; i++) {
printf "%" align[i] width[i] "s ", vals[n,i]
}
print vals[n,NF]
}
}
然后将其称为:
$ stat --printf="%A\t%a\t%h\t%U\t%G\t%s\t%.19y\t%n\n" . .* | awk -f tst.awk
答案2
您可以使用column -t your_file
(但据我所知,它没有得到正确的合理位)
输出:
drwxr-xr-x 755 4 boss boss 4096 2021-10-29 22:49:12 .
drwxr-xr-x 755 4 boss boss 4096 2021-10-29 22:49:12 .
drwxr-xr-x 755 36 boss boss 4096 2021-11-01 11:30:24 ..
-rw-r--r-- 644 1 boss boss 97708 2021-11-01 11:30:16 .custom
-rw-r--r-- 644 1 boss boss 4013 2021-10-11 22:04:04 .custom-dk