以前、UNIX 端末上で複数のファイルを並べて表示する方法と、ansicolum コマンドを使って実現する方法について書いた。
ansicolumn でファイルを並べて表示する
結論は簡単で、ansicolumn
コマンドに複数のファイルを与えて実行すればいいだけだった。
3つのデータを同時に見たい
ファイルを並べてみたいことは結構あって、そんな時に便利に使っていた。ターミナルの幅が狭くて表示できない場合には、画面を広げるとか、フォントを小さくするとかで対応することができる。
最近になって、ある2つのファイルを並べて表示したくなった。1つのファイルに用語のリストが含まれていて、もう1つのファイルには、同じ行に含まれる用語の日本語訳と、その読みがタブで区切られて書かれている。この3つのデータを同時に並べてみたいというのは自然な発想だろう。
まあ、ansicolumn
を使って2つのファイルを並べて表示することはできるのだが、最初のファイルには1つの項目、2番目のファイルには2つの項目が含まれているので、1番目と2番目の項目の間に隙間がありすぎてスカスカするし、離れているので対応が取りにくいのだ。
paste でつなげる
まず考えられるのは、2つのファイルを組み合わせて1つのデータにする方法だ。これは、最初の記事で紹介した paste
コマンドを使えばいい。
paste terms.txt japanese.txt | column -t
のようにすれば、3つの項目を整列して表示することができる。
ここで問題なのは、それぞれのデータの中には空白文字が含まれていることと、タブは1つではなく、桁合わせのために複数入っていることだ。タブが1つに限られていれば column
コマンドの -s
オプションでタブを指定すればいい。roff の tbl 形式はそのようなものだが、決して見やすい形式ではない。
ansicolumn -r オプション
こういう時のために、今年の夏に ansicolumn
コマンドに -r
オプションを追加してあった。普通は -s
オプションには分割に使う文字を列挙するのだが、-r
オプションと一緒に使うと -s
の値を正規表現として解釈するようになる。
paste terms.txt japanese.txt | ansicolumn -rs '\t+'
こうすると、タブ文字の連続を区切りとして要素を整列することができる。
ちなみに、今回のケースであれば、sed
で複数のタブを1つに変換すれば column
コマンドで処理することもできる。もっと複雑なパターンを指定したい場合や、分割文字を出力に含めたい場合には -r
オプションが不可欠となる。
ansicolumn --cell オプション
これがすべてのファイルに通用するわけではないので、ansicolumn
コマンドに新しいオプションを追加して、それぞれのファイルの表示幅を指定できるようにした。ansicolumn
には、元々カラムの幅を指定するための --pane-width
(-S
) というオプションがある。しかし、column
コマンドは同一種類のデータをマルチカラムで表示するためのものなので、処理の都合上、この幅を可変にするのは難しい。GNU の ls
などはそんな処理をしているようだが、恐ろしくてソースを見たくない。おそらく、バックトラックのようなアルゴリズムを実装する必要がある。
絶対値指定
難しい原因は、横方向のパラメータが変化すると縦方向の処理に影響が出るからだ。そして、縦方向のパラメータが変化すると、また横方向の処理に影響が出るのだ。しかし、複数ファイルを表示するパラレルモードでは、縦方向の変化は発生しない。というわけで、パラレルモードだけで有効になる --cell
というオプションを追加した。
ansicolumn terms.txt japanese.txt --cell 40,120
のように使うと term.txt
を40カラム、japanese.txt
を120カラムで表示する。
相対指定
表示幅を相対的に指定することもできる。デフォルトでは、2つのファイルであれば、それぞれ画面の半分の幅で表示する。もしそれが80カラムだとしたら、次のようにすると、上の例と同じ結果になる。
ansicolumn term.txt japanese.txt --cell -40,+40
最長行指定
それぞれのファイルに含まれる最長行を基準にすることもできる。
ansicolumn term.txt japanese.txt --cell =
のように --cell
オプションの値として =
を指定する。
=
の値には最大値を指定することができて、
ansicolumn term.txt japanese.txt --cell =40,=120
のようにすると、それぞれのファイルの最長のデータが40カラムと120カラムを超えければその長さ、それより長かったら40と120に設定される。
たとえば、
ansicolumn --cell =,=80,=80 /etc/{paths,passwd,services}
を実行するとこうなる。
/etc/passwd
と /etc/services
は80カラムを超えるので、それぞれ80カラムで折り返されている。
TODO
ansicolumn
の他のパラメータは逆ポーランド記法で式が書けるようになっているが、--cell
オプションはそうなっていない。そうすれば、比率を指定して画面を分割するような使い方が可能になる。しかし、元々、他にやりたい作業があってそのために実装したので、これにあまりかまけていると、本来の作業が一向に進まない。そのうち、気が向いたら実装するかもしれない。