How to format data with Column in Linux

Column is a free and open source utility usually installed as part of the util-linux package in all the most common Linux distribution, and therefore included in even the most minimal installations. With this utility we can organize the content of files or the output of other commands in columns, creating pretty tables or even producing JSON formatted documents. 

In this tutorial we see how to use the “column” utility to format the content of a file as a table or JSON on Linux.

In this tutorial you will learn:

  • How to use column to format the content of a file as a table
  • How to name columns
  • How to specify the input separator
  • How to specify the output separator
  • How to format the content of a file as JSON
Introduction to Column
Introduction to Column
Software requirements and conventions used
Category Requirements, Conventions or Software Version Used
System Distribution independent
Software column
Other None
Conventions # – requires given linux-commands to be executed with root privileges either directly as a root user or by use of sudo command $ – requires given linux-commands to be executed as a regular non-privileged user

Formatting output as a table

As we said in the introduction, we can  use the “Column” utility to organize the content of a file or the output of other commands in a table. Here are some real-world use cases of the command. On Unix-like operating systems, the /etc/fstab file contains information about the filesystems which must be automatically mounted on boot. Said information are organized in columns, each holding a specific information. Here is a minimal example of how the file looks like:

#
# /etc/fstab
# Created by anaconda on Wed Nov  2 08:18:43 2022
#
# Accessible filesystems, by reference, are maintained under '/dev/disk/'.
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info.
#
# After editing this file, run 'systemctl daemon-reload' to update systemd
# units generated from this file.
#
/dev/mapper/rl-root     /                       xfs     defaults        0 0
UUID=2a9dc637-e858-407c-81dc-26ea16ac6c57 /boot                   xfs     defaults        0 0
/dev/mapper/rl-swap     none                    swap    defaults        0 0

As you can see, only two filesystems are included in the /etc/fstab file, and, due to the different length of strings, columns are not well aligned. This, of course, is not relevant from a functionality point of view, but it’s pretty ugly; we can use the “column” utility to “beautify” it.



The “column” command accepts the path of an input file as argument, however, in this case, we want to remove comments from the content of the file before processing it. To accomplish this task we can use sed and a shell pipe:

$ sed /^#/d /etc/fstab | column --table

In the example above we invoked the “column” utility with the --table option (-t): this is needed to create a table. Here is the result we obtain:

/dev/mapper/rl-root                        /      xfs   defaults  0  0
UUID=2a9dc637-e858-407c-81dc-26ea16ac6c57  /boot  xfs   defaults  0  0
/dev/mapper/rl-swap                        none   swap  defaults  0  0

Providing columns names

The output produced by “column” is nicely aligned, however, in certain situations we may want to add an additional “row” containing the column names. In order to do that, we can launch the utility with the --table-columns option (-N), and pass the comma-separated list of columns names as argument. In this case, we could run:

$ sed /^#/d /etc/fstab | column --table --table-columns BLOCK_DEVICE,MOUNTPOINT,FILESYSTEM,MOUNT_OPTIONS,DUMP,FSCK_ORDER

The command above produces the following result:

BLOCK_DEVICE                               MOUNTPOINT  FILESYSTEM  MOUNT_OPTIONS  DUMP  FSCK_ORDER
/dev/mapper/rl-root                        /           xfs         defaults       0     0
UUID=2a9dc637-e858-407c-81dc-26ea16ac6c57  /boot       xfs         defaults       0     0
/dev/mapper/rl-swap                        none        swap        defaults       0     0

Changing the input separator

By default the “column” utility uses the whitespace character as input delimiter, in order to organize the content of a file in columns. This works well in certain situations, like the one we saw in the previous example, however, sometimes we may need to specify a different character to be used as separator. Let’s take a look, for example to how information are organized in the /etc/passwd file. This file, as we know, is used to store accounts information; the colon character (“:”) is used to separate fields in each entry:

tux:x:1000:1000:tux:/home/tux:/bin/bash



The line above contains information about the “tux” user. The first field of the line reports the username. The second is used for the password: here an x means that the password is hashed and stored in the /etc/shadow file. The third and fourth fields report, respectively the UID (User ID) and the GID (Group ID) of the user primary group. The fifth field is the so called GECOS field: it can contain additional user information as his/her full name or telephone number. The sixth field contains the path of the user HOME directory. The seventh and last field, instead, contains information about the default shell or command for the user, which in this case is “/bin/bash”.

To format the content of this file in a “pretty” table, we have to tell the “column” utility to use a “:” as separator. We can do that it via the --separator option (-s):

$ column --table --separator=":" /etc/passwd

The result we obtain is the following:

root                 x  0      0      root                                           /root                      /bin/bash
bin                  x  1      1      bin                                            /bin                       /sbin/nologin
daemon               x  2      2      daemon                                         /sbin                      /sbin/nologin
adm                  x  3      4      adm                                            /var/adm                   /sbin/nologin
lp                   x  4      7      lp                                             /var/spool/lpd             /sbin/nologin
sync                 x  5      0      sync                                           /sbin                      /bin/sync
shutdown             x  6      0      shutdown                                       /sbin                      /sbin/shutdown
halt                 x  7      0      halt                                           /sbin                      /sbin/halt
mail                 x  8      12     mail                                           /var/spool/mail            /sbin/nologin
operator             x  11     0      operator                                       /root                      /sbin/nologin
games                x  12     100    games                                          /usr/games                 /sbin/nologin
ftp                  x  14     50     FTP User                                       /var/ftp                   /sbin/nologin
nobody               x  65534  65534  Kernel Overflow User                           /                          /sbin/nologin
systemd-coredump     x  999    997    systemd Core Dumper                            /                          /sbin/nologin
dbus                 x  81     81     System message bus                             /                          /sbin/nologin
polkitd              x  998    996    User for polkitd                               /                          /sbin/nologin
avahi                x  70     70     Avahi mDNS/DNS-SD Stack                        /var/run/avahi-daemon      /sbin/nologin
rtkit                x  172    172    RealtimeKit                                    /proc                      /sbin/nologin
sssd                 x  997    993    User for sssd                                  /                          /sbin/nologin
pipewire             x  996    992    PipeWire System Daemon                         /var/run/pipewire          /sbin/nologin
libstoragemgmt       x  995    991    daemon account for libstoragemgmt              /var/run/lsm               /sbin/nologin
tss                  x  59     59     Account used for TPM access                    /dev/null                  /sbin/nologin
geoclue              x  994    989    User for geoclue                               /var/lib/geoclue           /sbin/nologin
cockpit-ws           x  993    988    User for cockpit web service                   /nonexisting               /sbin/nologin
cockpit-wsinstance   x  992    987    User for cockpit-ws instances                  /nonexisting               /sbin/nologin
rpc                  x  32     32     Rpcbind Daemon                                 /var/lib/rpcbind           /sbin/nologin
flatpak              x  991    986    User for flatpak system helper                 /                          /sbin/nologin
colord               x  990    985    User for colord                                /var/lib/colord            /sbin/nologin
setroubleshoot       x  989    984    SELinux troubleshoot server                    /var/lib/setroubleshoot    /sbin/nologin
clevis               x  988    983    Clevis Decryption Framework unprivileged user  /var/cache/clevis          /usr/sbin/nologin
gdm                  x  42     42                                                    /var/lib/gdm               /sbin/nologin
gnome-initial-setup  x  987    982                                                   /run/gnome-initial-setup/  /sbin/nologin
rpcuser              x  29     29     RPC Service User                               /var/lib/nfs               /sbin/nologin
sshd                 x  74     74     Privilege-separated SSH                        /usr/share/empty.sshd      /sbin/nologin
chrony               x  986    981                                                   /var/lib/chrony            /sbin/nologin
dnsmasq              x  985    980    Dnsmasq DHCP and DNS server                    /var/lib/dnsmasq           /sbin/nologin
tcpdump              x  72     72                                                    /                          /sbin/nologin
systemd-oom          x  978    978    systemd Userspace OOM Killer                   /                          /usr/sbin/nologin
tux                  x  1000   1000   tux                                            /home/tux                  /bin/bash

Chaining the output separator

The input separator, as we saw, is used to tell “column” which character should use to organize the content of a file in columns. The output separator, instead, is used  in the output of the command, to delimiter the various fields. By default, two spaces are used as output separator; in order to use a different character, we must pass it as argument to the --output-separator option (-o).

In the following example, we use | character as output separator:

$ column --table --separator ":" --output-separator "|" /etc/passwd

We  obtain:

root               |x|0    |0    |root                                         |/root                    |/bin/bash
bin                |x|1    |1    |bin                                          |/bin                     |/sbin/nologin
daemon             |x|2    |2    |daemon                                       |/sbin                    |/sbin/nologin
adm                |x|3    |4    |adm                                          |/var/adm                 |/sbin/nologin
lp                 |x|4    |7    |lp                                           |/var/spool/lpd           |/sbin/nologin
sync               |x|5    |0    |sync                                         |/sbin                    |/bin/sync
shutdown           |x|6    |0    |shutdown                                     |/sbin                    |/sbin/shutdown
halt               |x|7    |0    |halt                                         |/sbin                    |/sbin/halt
mail               |x|8    |12   |mail                                         |/var/spool/mail          |/sbin/nologin
operator           |x|11   |0    |operator                                     |/root                    |/sbin/nologin
games              |x|12   |100  |games                                        |/usr/games               |/sbin/nologin
ftp                |x|14   |50   |FTP User                                     |/var/ftp                 |/sbin/nologin
nobody             |x|65534|65534|Kernel Overflow User                         |/                        |/sbin/nologin
systemd-coredump   |x|999  |997  |systemd Core Dumper                          |/                        |/sbin/nologin
dbus               |x|81   |81   |System message bus                           |/                        |/sbin/nologin
polkitd            |x|998  |996  |User for polkitd                             |/                        |/sbin/nologin
avahi              |x|70   |70   |Avahi mDNS/DNS-SD Stack                      |/var/run/avahi-daemon    |/sbin/nologin
rtkit              |x|172  |172  |RealtimeKit                                  |/proc                    |/sbin/nologin
sssd               |x|997  |993  |User for sssd                                |/                        |/sbin/nologin
pipewire           |x|996  |992  |PipeWire System Daemon                       |/var/run/pipewire        |/sbin/nologin
libstoragemgmt     |x|995  |991  |daemon account for libstoragemgmt            |/var/run/lsm             |/sbin/nologin
tss                |x|59   |59   |Account used for TPM access                  |/dev/null                |/sbin/nologin
geoclue            |x|994  |989  |User for geoclue                             |/var/lib/geoclue         |/sbin/nologin
cockpit-ws         |x|993  |988  |User for cockpit web service                 |/nonexisting             |/sbin/nologin
cockpit-wsinstance |x|992  |987  |User for cockpit-ws instances                |/nonexisting             |/sbin/nologin
rpc                |x|32   |32   |Rpcbind Daemon                               |/var/lib/rpcbind         |/sbin/nologin
flatpak            |x|991  |986  |User for flatpak system helper               |/                        |/sbin/nologin
colord             |x|990  |985  |User for colord                              |/var/lib/colord          |/sbin/nologin
setroubleshoot     |x|989  |984  |SELinux troubleshoot server                  |/var/lib/setroubleshoot  |/sbin/nologin
clevis             |x|988  |983  |Clevis Decryption Framework unprivileged user|/var/cache/clevis        |/usr/sbin/nologin
gdm                |x|42   |42   |                                             |/var/lib/gdm             |/sbin/nologin
gnome-initial-setup|x|987  |982  |                                             |/run/gnome-initial-setup/|/sbin/nologin
rpcuser            |x|29   |29   |RPC Service User                             |/var/lib/nfs             |/sbin/nologin
sshd               |x|74   |74   |Privilege-separated SSH                      |/usr/share/empty.sshd    |/sbin/nologin
chrony             |x|986  |981  |                                             |/var/lib/chrony          |/sbin/nologin
dnsmasq            |x|985  |980  |Dnsmasq DHCP and DNS server                  |/var/lib/dnsmasq         |/sbin/nologin
tcpdump            |x|72   |72   |                                             |/                        |/sbin/nologin
systemd-oom        |x|978  |978  |systemd Userspace OOM Killer                 |/                        |/usr/sbin/nologin
tux                |x|1000 |1000 |tux                                          |/home/tux                |/bin/bash

Formatting the content as JSON

One really nice feature of the “column” utility is the ability to format the content of a file as JSON, using the content of the columns as values and columns names as keys. The --json option (-J) is used to accomplish this task. The option is accepted only if used together with --table-columns, which, as we saw before, is used to specify columns names:

$ column --table --separator=":" --table-columns username,password,uid,gid,gecos,home,shell --json /etc/passwd



Here is the output produced by the command above (we conveniently truncated it):

{
   "table": [
      {
         "username": "root",
         "password": "x",
         "uid": "0",
         "gid": "0",
         "gecos": "root",
         "home": "/root",
         "shell": "/bin/bash"
      },{
         "username": "bin",
         "password": "x",
         "uid": "1",
         "gid": "1",
         "gecos": "bin",
         "home": "/bin",
         "shell": "/sbin/nologin"
      },{
         "username": "daemon",
         "password": "x",
         "uid": "2",
         "gid": "2",
         "gecos": "daemon",
         "home": "/sbin",
         "shell": "/sbin/nologin"
      }, # remaining output truncated
   ]
}

As you can see above, the key associated to the list containing all the file entries, is called “table”. We can change that by using --table-name option (-n) and pass the name we want to use as argument.

Conclusions

In this tutorial we learned how to use the “command” utility to format the content of a file as a table or as JSON. We saw how to create a table, how to provide and include columns names in the output produced by the command and how to specify the input and output separators. Finally, we saw how to format the output as JSON, using column names as keys, and their content as values. There are other ways we can format the content of files using “column”. Take a look at the manual to get to know all of them!