コマンドの出力が縦にずらっと並んでいるのに、どの値がどの項目なのか読み取れない。
設定ファイルやログをそのまま画面に出して、目で列を数えたことはありませんか。
そんなときに手が届くのが column です。
名前のとおり、入力を列としてそろえて表の形に整えるだけの小さなコマンドなのです。
ただし区切り文字の扱いに独特の癖があり、知らずに使うときれいにそろったつもりの表が静かにずれます。
column -t は「幅をそろえるだけ」の道具
column には多くのオプションが並んでいますが、実務でまず覚えるのは表を作る -t の1つだけ。
空白で区切られた入力を受け取り、各列のいちばん長い値に合わせて幅をそろえるという単純な仕事をします。
$ cat sample.txt
id name role
1 sasaki engineer
2 kamome writer
10 test qa
$ column -t sample.txt
id name role
1 sasaki engineer
2 kamome writer
10 test qa
値そのものは何ひとつ変わっておらず、間の空白の数だけが調整されている点に注目してください。
集計も並べ替えもしないので、awk や sort の結果を最後に人間が読む形へ落とすための出口として使うのが素直な役割になります。
逆に言うと、値の中に空白が混じっている入力にはそのままでは通用しません。
$ df -h | head -3 | column -t
Filesystem Size Used Avail Use% Mounted on
C:/Program Files/Git 931G 721G 211G 78% /
パスに空白が入っていたせいで1列ぶんずれ、見出しの Mounted on まで2列に割れてしまいました。
この手の入力は、後述する区切り文字の指定とセットで扱うのが前提になるでしょう。
区切り文字の指定でつまずく2つの落とし穴
CSV やコロン区切りのファイルを整えるときは -s で区切り文字を渡します。
ここが column でいちばん誤解されやすいところで、私も最初は素直に文字列を渡して首をかしげました。
-s は「文字列」ではなく「文字の集合」
ヘルプの表記は possible table delimiters、つまり「区切りになりうる文字の一覧」です。
カンマと空白の2文字を渡すと「カンマと空白の並び」ではなく「カンマまたは空白」として解釈されます。
$ printf 'a, b c,d\n1, 2 3,4\n' | column -s', ' -t
a b c d
1 2 3 4
3列のつもりで書いた行が、空白でも切られて4列に増えてしまいました。
カンマ区切りを扱いたいなら、渡すのはカンマ1文字だけにとどめるのが安全です。
どこで切られたのか自信が持てないときは、-o に縦棒などの記号を渡して境目を可視化すると一目で判断できました。
空のフィールドは黙って詰められる
もう一つの罠が、値の入っていないフィールドの扱い。
連続した区切り文字は1つとみなされ、空の列がまるごと消えて右側が1つずつ左へずれます。
$ printf 'a,,c\n1,2,3\n' | column -s, -t
a c
1 2 3
1行目の c と2行目の 3 は本来そろうはずなのに、見事に食い違ってしまいました。
手元で試して効いたのは、-N で列名を明示的に与える方法でした。
$ printf 'a,,c\n1,2,3\n' | column -s, -t -N c1,c2,c3
c1 c2 c3
a c
1 2 3
列の数が先に決まるため、空のフィールドが空欄のまま正しい位置に残りました。
列名を付けたくない場合は、column に渡す前に awk などで空欄をハイフンに埋めておく手も使えるでしょう。
表として整えるオプションを足す
-t と -s だけでも十分実用になりますが、読み手のことを考えるならもう少し手を入れられます。
列名・右寄せ・区切り記号
数値の列は左寄せのままだと桁がそろわず、大小の比較がしづらくなりますね。
-R に列番号を渡すと、その列だけ右寄せに変わるのです。
$ printf 'name,count\nfoo,5\nbarbaz,1234\n' | column -s, -t -R 2
name count
foo 5
barbaz 1234
桁がそろうだけで、数字の並びが一目で比較できる表に変わりました。
列と列の境目をはっきりさせたいときは、-o で好きな区切り記号を差し込めます。
JSON で出して次の処理へ渡す
人間が読むためではなく、次のコマンドへ渡したい場面もありますね。
-J を付けると、列名をキーにした JSONがそのまま出てきます。
$ printf '1,sasaki\n2,kamome\n' | column -s, -t -J -N id,name
{
"table": [
{
"id": "1",
"name": "sasaki"
},{
"id": "2",
"name": "kamome"
}
]
}
雑に取り出したテキストを jq へ流し込む前段として、なかなか使い勝手のよい経路です。
値がすべて文字列として入る点だけは頭の隅に置いておくと、後段で数値として比較したときに慌てずに済みますね。
ここまでに挙げた -N や -R や -J は util-linux 版のオプションなので、手元の実装が違うと使えません。
オプションが効かないと感じたら、まず column –version で実装を確かめるのが近道でしょう。
日本語がずれるときはロケールを疑う
日本語を含む表を作ると、幅がそろわない現象に出くわすことがあります。
全角の文字は表示上2文字分の幅を取りますが、ロケールが設定されていないと column はそれを1文字として数えてしまうのです。
$ column -s, -t jp.csv
コマンド 説明
grep 行を検索する
find ファイルを探す
$ LC_ALL=ja_JP.UTF-8 column -s, -t jp.csv
コマンド 説明
grep 行を検索する
find ファイルを探す
同じ入力でも、ロケールを渡した2回目だけが正しくそろっています。
手元の環境では LANG が空だったため、LC_ALL を明示するだけで日本語の列が一発で整いました。
日本語の表がどうしてもそろわないときは、column のオプションを増やす前に環境変数を疑うのが早道でしょう。
列を切り出したり貼り合わせたりする前段の操作は、cut・paste の記事にまとめてあります。
最後に
column は列をそろえるだけの道具で、値を加工する機能は持ちません。
だからこそ責任範囲がはっきりしていて、パイプの最後尾に置く整形係として素直に働いてくれます。
覚えることは -t で表にする、-s は文字の集合として渡る、日本語がずれたらロケールを見る、この3点だけ。
本記事の実行例は Windows の Git Bash 上で、GNU bash 5.2.37 と util-linux 2.40.2 の column を使って確かめました。
ログを目で追って列を数える作業に心当たりがあれば、パイプの右端に足してみてください。
以上です。










コメントを残す