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

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!