先の2つの記事で、UNIX 端末上で複数のファイルを並べて表示する方法と、ansicolum コマンドについて書いた。今回は、ansicolumn コマンドを改造して、複数ファイルの同時表示対応したという話題。
ansicolumn で複数ファイルを並べて表示する
ファイルを複数指定するだけ
まず、ansicolumn コマンドのインストールについてはこちらを参照。と言っても cpanm App::ansicolumn
するだけ。cpanm (App::cpanminus) のインストールについては、環境によって違うので調べてください。
やり方は簡単。ansicolumn コマンドの引数として2つ以上のファイルを指定するだけ。
以上...
--parallel/--no-parallel オプション
...でもなんなので、もう少し説明する。とりあえず、コマンドやオプションをあれこれ組み合わせるのに比べると、非常にシンプルなインタフェースで実現できることはわかっていただけたと思う。
一応、このために --parallel
というオプションを新設した。ただ、2つ以上のファイルが引数に指定されると自動的に有効になるので、わざわざ指定する必要はない。--parallel
オプションが指定されると、ボーダー表示 --border
(-B
)、行の折り返し --linestyle=wrap
、画面の幅一杯に表示 --widen
(-W
) オプションが有効になる。 そのため、ファイルを複数指定しただけで、上の例のような出力形式になる。デフォルトのボーダースタイルは box
。
逆に、無効にしたい場合には --no-parallel
オプションを指定する。--no-parallel
モードで複数ファイルを処理すると、それぞれのファイルを逐次的に処理する。ただし、横方向のパラメータに関しては、すべてのファイルのデータに基づいて統一的に決定する。一方で、縦方向のパラメータ、たとえばページの高さなどは、それぞれのファイル毎に決定する。各ファイル毎にすべてのパラメータを決めていたのでは、個別にコマンドを実行するのと変わらないからだ。
上の例では、2つのファイルのすべての行の最大長からカラム数を2に設定し、それはすべてのファイルに対して適用される。
カラム数指定
次の例は、week コマンドを使って12ヶ月分のカレンダーのファイルを用意して ansicolumn で表示している。
この例だと、5ヶ月以上のデータを表示しようとすると、表示幅が足りなくなってしまう。
このような場合は、-C
オプションでカラム数を指定すれば、その単位で出力することができる。
ドキュメント表示
複数のドキュメントを並べて表示すると、このようになる。--parallel
オプションではページ制御の機能はすべて無効になるので、それぞれのファイルの内容は最も長いファイルに合わせてすべて連続して出力され、足りない部分は空白で埋められる。この例では、-p
(--paragraph
) と -D
(--document
) オプションを指定しているので、連続する空白以外の行の間には空行が挿入され、禁則処理が有効になっている。
ansicolumn を2段重ねで使う
ややトリッキーだが、ansicolumn を組み合わせて使うこともできる。次の例では、新旧仮名使いの資料をそれぞれ2カラムのページモードで出力した結果を、さらに複数ファイルで並べて表示している。
$ ansicolumn <(ansicolumn -w2/3- -pDPC2 sorekara-old.txt) <(ansicolumn -w2/3- -pDPC2 sorekara-new.txt) --border=none
前の記事では説明しなかったが、ansicolumn の幅や高さの指定では、-w2/3-
のような記法を使うことができる。-w
は、全体の幅を指定するオプションで、2/3-
は逆ポーランド記法の式だ。スタックには画面の幅が最初に積まれているので、これは width / 2 - 3
という意味になる。半分よりやや狭い幅で2カラム出力した結果を並べて表示しているというわけだ。
diff を見る
上の例は夏目漱石の「それから」の新旧仮名遣いによるものだ。両者を比較したいのであれば、sdif コマンドなどを使うのが便利だ。
ただ、これはデータチェックのための体裁であって、文章を読ませようというのとはちょっと違う。少々工夫すると、diff の結果を ansicolumn コマンドで読みやすい形式で出力することができた。
上の例は、sdif がバックエンドで使っている cdif コマンドを2回使っている。cdif の、--no-old
, --no-new
オプションを使うと、いずれか一方のファイルの内容だけを表示することができる。
ちなみに、cdif は、文字単位ではなく単語単位で比較する。上の例では、さらに mecab コマンドによる形態素解析の結果に基づいて比較をおこなっている。若干区切りにおかしい点があるのは、旧仮名使いによるものもあるが、そもそも現代語とは少し違うので、うまく対応できていないからだろう。
他の ANSI 対応ツール
ansicolumn 以外にも、ansifold, ansiecho, ansiexpand などの ANSI 対応ツールがあるので、よかったら試してみていただきたい。いずれも、UNIX の fold, echo, expand/unexpand 互換の仕様をベースに拡張してある。実は、これらのツールは、ほとんど Text::ANSI::Fold という Perl モジュールをベースに作られている。このモジュールは、与えられた文字列を指定された長さで分割するという、極めて単純な機能しか持っていない。