复制 ls 在使用 ls 两次时所做的正确调整

Replicate the right justification that ls does when using ls twice

如果我有两个文件,tmp.txttmp.pdf,一大一小,当我输入 ls -al tmp.* 时,一切都很好地右对齐,我得到这个输出

-rw-r--r-- 1 simon simon 615316 Oct 17 20:55 tmp.pdf
-rw-r--r-- 1 simon simon      0 Oct 17 20:55 tmp.txt

出于无关紧要的原因,我希望能够将两个单独的 ls -al 命令的输出写入一个文件,然后 cat 该文件并获得相同的输出。但当然,如果我这样做:

ls -al tmp.txt > foo
ls -al tmp.pdf >> foo

然后cat foo,我明白了

-rw-r--r-- 1 simon simon 0 Oct 17 20:55 tmp.txt
-rw-r--r-- 1 simon simon 615316 Oct 17 20:55 tmp.pdf

有没有办法模仿 ls -al 产生的合理输出?显然,我可以使用 wc -c tmp.pdf 等来确定哪个输出最大,但是我如何将该信息转换为代码,以便在第一行的 0 之前放置必要数量的空格?非常感谢任何建议。

是的。只需使用 column

$ (ll tmp.small; ll tmp.big) | column -t
-rw-r--r--  1  myuser  myuser  0       Oct  18  11:24  tmp.small
-rw-r--r--  1  myuser  myuser  113616  Oct  18  11:42  tmp.big

但是,如果您的文件名包含空格,则这些名称将无法正确打印。如果您的 column 支持 -l 选项,那么最简单的解决方法是更改​​为 column -t -l 9 以将列总数限制为 9。另一种解决方法是使用 stat 来模拟ls输出

$ (
> stat --printf="%A\t%h\t%U\t%G\t%s\t%y\t%n\n" "tmp with space.txt"
> stat --printf="%A\t%h\t%U\t%G\t%s\t%y\t%n\n" tmp.small
> stat --printf="%A\t%h\t%U\t%G\t%s\t%y\t%n\n" tmp.big
> ) | column -t -s $'\t'
-rw-r--r--  1  myuser  myuser  1307    2020-10-18 12:08:45.360000000 +0700  tmp with space.txt
-rw-r--r--  1  myuser  myuser  0       2020-10-18 11:24:21.650000000 +0700  tmp.small
-rw-r--r--  1  myuser  myuser  113616  2020-10-18 11:42:04.150000000 +0700  tmp.big

名称中带有制表符或换行符的文件仍然不起作用。您可以尝试使用 stat --printf="%A[=16=]%h[=16=]%U[=16=]%G[=16=]%s[=16=]%Y[=16=]%n\n" tmp* | column -t -s $'[=16=]' -l 9 将分隔符更改为空,但不知何故,我的 column 无法将 [=18=] 识别为分隔符。不确定其他列版本,只需在您的 PC 上尝试一下,然后查看