我可以对列选项卡大小进行后格式化,以使间距成为 Linux 中的最小公分母吗?

我可以对列选项卡大小进行后格式化,以使间距成为 Linux 中的最小公分母吗?

我可以用来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很好,但相当“间隙”。这让我很好奇,是否有一种通用方法可以对这样的任何输出进行后处理,使得列将处于单空间间隙的最低公分母,即是否有一种通用方法可以将上面的内容调整为类似于下面的内容使用awkorsed或类似的(如果可能的话,我也将数字列右对齐作为“理想”输出)?

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

相关内容