## 21.16. Make Columns Automatically with column

Go to http://examples.oreilly.com/upt3 for more information on: column

Another column-making program, besides cols and pr (Section 21.15), is the creatively named utility column. It tries to determine the terminal width, which you can override with the -c option (`-c 132`, for example, gives 132 columns: handy for printing on wide line-printer paper.) The -x option fills columns before rows -- similar to pr with its `-`n option and cols -d.

What makes column different from the others is its -t option. This reads input data that's already in columns and rebalances the columns into a table with variable-width columns. Say what? This is easiest to see with an example, and the column(1) manual page has a good one.

If you'd like to add column headings to ls -l output, it can be a pain to try to make headings that each take the same number of characters as the data below them. For instance, the first field on each line, the permissions, takes 10 characters, but if you want to use the heading "PERM", which takes only 4 characters, you need to balance it by adding 6 spaces after. Using `column -t`, you can balance these automatically. Here's an example. The first command is plain ls -l. In the second and third examples, I use sed 1d (Section 34.1) to delete the `total` `n` line from ls, and subshells (Section 24.4) to make both commands use the same standard output; this is important only in the third command, where I pipe the combined stdout to column for balancing:

`;` Section 28.16, `>` Section 28.12

>     $ ls -lo
>     total 1644
>     -r--r--r--    1 jpeek     1559177 Sep 19  1999 ORA_tifs.tgz
>     -rw-rw-r--    1 jpeek        4106 Oct 21  1999 UPT_Russian.jpg
>     -rw-rw-r--    1 jpeek      101944 Nov 19 09:30 london_dusk-livesights.xwd.gz
>     dr-xr-xr-x    2 jpeek        4096 Dec 12  1999 me
>     $ (echo "PERM      LINKS OWNER        SIZE MON DY TM/YR NAME"; \
>     > ls -lo | sed 1d)
>     PERM      LINKS OWNER        SIZE MON DY TM/YR NAME
>     -r--r--r--    1 jpeek     1559177 Sep 19  1999 ORA_tifs.tgz
>     -rw-rw-r--    1 jpeek        4106 Oct 21  1999 UPT_Russian.jpg
>     -rw-rw-r--    1 jpeek      101944 Nov 19 09:30 london_dusk-livesights.xwd.gz
>     dr-xr-xr-x    2 jpeek        4096 Dec 12  1999 me

>     $ (echo PERM LINKS OWNER SIZE MONTH DAY HH:MM/YEAR NAME; \
>     > ls -lo | sed 1d) | column -t
>     PERM        LINKS  OWNER  SIZE     MONTH  DAY  HH:MM/YEAR  NAME
>     -r--r--r--  1      jpeek  1559177  Sep    19   1999        ORA_tifs.tgz
>     -rw-rw-r--  1      jpeek  4106     Oct    21   1999        UPT_Russian.jpg
>     -rw-rw-r--  1      jpeek  101944   Nov    19   09:30       london_dusk-livesights.xwd.gz
>     dr-xr-xr-x  2      jpeek  4096     Dec    12   1999        me

My feeble attempt in the second example took a lot of trial-and-error to get the right spacing, and I still had to cram `DY` over the tiny sixth column and `TM/YR` over the seventh. In the third example, column automatically adjusted the column width to compensate for the `HH:MM/YEAR` heading. Unfortunately, the long filename london_dusk-livesights.xwd.gz ran off the right edge (past column 80, my window width) -- but there was nothing column could do in this case because the combined header+columns were just too wide.

-- JP

Copyright © 2003 O'Reilly & Associates. All rights reserved.