0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ターミナルで複数のファイルを並べて表示する方法(改造編)

Last updated at Posted at 2023-11-26

以前、UNIX 端末上で複数のファイルを並べて表示する方法と、ansicolum コマンドを使って実現する方法について書いた。

ansicolumn でファイルを並べて表示する

結論は簡単で、ansicolumn コマンドに複数のファイルを与えて実行すればいいだけだった。

スクリーンショット 2022-10-12 20.18.22.png

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}

を実行するとこうなる。

スクリーンショット 2023-11-26 19.07.38.png

/etc/passwd/etc/services は80カラムを超えるので、それぞれ80カラムで折り返されている。

TODO

ansicolumn の他のパラメータは逆ポーランド記法で式が書けるようになっているが、--cell オプションはそうなっていない。そうすれば、比率を指定して画面を分割するような使い方が可能になる。しかし、元々、他にやりたい作業があってそのために実装したので、これにあまりかまけていると、本来の作業が一向に進まない。そのうち、気が向いたら実装するかもしれない。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?