0

If I have two files, tmp.txt and tmp.pdf, one large and one small, when I type ls -al tmp.* everything is nicely right justified and I get this output

-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

For a reason that doesn't matter, I want to be able to write the output of two separate ls -al commands to a file, then cat the file and obtain the same output. But of course, if I do this:

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

and then cat foo, I get this

-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

Is there a way of mimicking the justified output that ls -al produces? Obviously, I can use wc -c tmp.pdf etc to figure out which output is largest, but how would I translate that information into code that would put the requisite number of spaces before the 0 in the first line? Thanks very much for any suggestions.

phuclv
  • 37,963
  • 15
  • 156
  • 475
Leo Simon
  • 186
  • 1
  • 9

1 Answers1

1

Yes. Just use 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

However if your file names contain spaces then those names won't be printed correctly. If your column supports the -l option then the simplest fix is to change to column -t -l 9 to limit the total number of columns to 9. Another workaround is to use stat to simulate ls output

$ (
> 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

Files with tabs or newlines in their names still don't work though. You may try to change the delimiter to null with stat --printf="%A\0%h\0%U\0%G\0%s\0%Y\0%n\n" tmp* | column -t -s $'\0' -l 9 but somehow my column doesn't recognize \0 as the delimiter. Not sure about other columns versions, just try it on your PC and see

phuclv
  • 37,963
  • 15
  • 156
  • 475
  • Fabulous, thanks very much. I do everything I can to avoid spaces in file names, and certainly newlines, so the first solution works fine. It's not important, but i'm curious about `ll` which is not supported on my ubuntu 18.04 platform, nor can I `apt` it. Could you tell me where it came from please? – Leo Simon Oct 18 '20 at 18:16
  • @LeoSimon `ll` is the alias for `ls -alF` which exists by default in Ubuntu and most distros I've used – phuclv Oct 19 '20 at 00:14