The column command is extremely useful for formatting tabular data.
We will cover a number of useful examples such as pretty printing tables to dealing with CSV and JSON.
- Version of "column" utility
- Basic use
- Naming the columns
- Printing with the columns arranged in a different order
- Printing with certain columns removed
- Printing a JSON representation
- Setting a custom input delimiter/separator
- Setting a custom output separator
The column
utility is provided by the util-linux
package.
I'm using Fedora 26 with util-linux 2.30.2
.
On older systems, many of the features in this tutorial won't work
Let's look at some simple examples using the following input
$ ip -4 -brief address show
lo UNKNOWN 127.0.0.1/8
ens33 UP 10.10.0.129/24
ens37 UP 192.168.122.128/24
dummy0 UNKNOWN 172.16.32.64/32
We can use column -t
to tabulate it.
It looks mostly the same except it's slightly compacted.
$ ip -4 -brief address show | column -t
lo UNKNOWN 127.0.0.1/8
ens33 UP 10.10.0.129/24
ens37 UP 192.168.122.128/24
dummy0 UNKNOWN 172.16.32.64/32
Let's define the names of each column.
We use column -tN "n1,n2,n3"
$ ip -4 -brief address show | column -tN "dev,state,inet"
dev state inet
lo UNKNOWN 127.0.0.1/8
ens33 UP 10.10.0.129/24
ens37 UP 192.168.122.128/24
dummy0 UNKNOWN 172.16.32.64/32
Let's rearrange the order of the columns
We do this with -O
$ ip -4 -brief address show | column -tN "dev,state,inet" -O "inet,dev,state"
inet dev state
127.0.0.1/8 lo UNKNOWN
10.10.0.129/24 ens33 UP
192.168.122.128/24 ens37 UP
172.16.32.64/32 dummy0 UNKNOWN
What if we want to remove a particular column from our printout
We do this with -H
```
$ ip -4 -brief address show | column -tN "dev,state,inet" -H "state"
dev inet
lo 127.0.0.1/8
ens33 10.10.0.129/24
ens37 192.168.122.128/24
dummy0 172.16.32.64/32
```
Want JSON?
To do this, we simply use -tJN
$ ip -4 -brief address show | column -tJN "dev,state,inet"
{
"table": [
{"dev": "lo", "state": "UNKNOWN", "inet": "127.0.0.1/8"},
{"dev": "ens33", "state": "UP", "inet": "10.10.0.129/24"},
{"dev": "ens37", "state": "UP", "inet": "192.168.122.128/24"},
{"dev": "dummy0", "state": "UNKNOWN", "inet": "172.16.32.64/32"}
]
}
By default, the json object will be named "table"
We can set the name by putting --table-name
at the end of the command.
What about pretty-printing?,
We need to install jq
$ ip -4 -brief address show | column -tJN "dev,state,inet" --table-name "ipconfig" | jq
{
"ipconfig": [
{
"dev": "lo",
"state": "UNKNOWN",
"inet": "127.0.0.1/8"
},
{
"dev": "ens33",
"state": "UP",
"inet": "10.10.0.129/24"
},
{
"dev": "ens37",
"state": "UP",
"inet": "192.168.122.128/24"
},
{
"dev": "dummy0",
"state": "UNKNOWN",
"inet": "172.16.32.64/32"
}
]
}
What if we need to read CSVs or anything else that isn't delimited with whitespace?
We can read input delimited by an arbitrary string, set with -s
column -ts"," -N "dev,state,inet" < example.csv
dev state inet
lo UNKNOWN 127.0.0.1/8
ens33 UP 10.10.0.129/24
ens37 UP 192.168.122.128/24
dummy0 UNKNOWN 172.16.32.64/32
What about setting an arbitrary string to separate columns on the printout?
We use --output-separator=
$ column -ts"," -N "dev,state,inet" --output-separator=" | " <example.csv
dev | state | inet
lo | UNKNOWN | 127.0.0.1/8
ens33 | UP | 10.10.0.129/24
ens37 | UP | 192.168.122.128/24
dummy0 | UNKNOWN | 172.16.32.64/32
[root@PC ~]#