標準入力の指定の文字列に色をつけるツール colr

Go Conference ‘19 Summer in Fukuokaでも少し紹介したcolrです。

github.com

これはなに

まずは以下のスクリーンキャストをご覧ください

f:id:k1LoW:20190813073706g:plain

colrtail -F /path/to/access.log のようなログにカジュアルに色をつけるツールです。

$ tail -F /var/log/nginx/access.log | colr POST GET 404 500 search

のように何個でもカラーにしたい文字列を指定できます。

これだけです

色の指定もできませんし、その他のオプションもありません。 colr の後に引数としてカラーにしたい文字列を並べるだけです。

実は正規表現っぽい文字列を渡すと正規表現マッチに変更してくれますが、それでも使い方は変わりません。

これだけの機能、ただその分、何も考えずに利用できます。

是非ご利用ください。単純なツールですがなにげに重宝します。

Windowsにも対応しています!


以下余談です。

grep --color で色をつけてもパイプで繋ぐと色が消える。その仕組み

colr の紹介をすると「それ grep --color でいいんじゃ?」と言われます。「いや、私は絞込みたいわけではないんだよ」となるのですが、今回は別の話です。

例えば

$ tail -F /var/log/nginx/access.log | grep POST --color

とすると POST に色がつきますが、

$ tail -F /var/log/nginx/access.log | grep POST --color | grep search

とすると POST の色が消えてしまいます。

ちなみにこれを回避する方法は grep POST --color=always とすればいいのですが、パイプで繋ぐとなぜ色が消えるのか考えてみました。

ターミナル上で色をつける仕組み

ターミナルで色をつける仕組みは特殊なエスケープコードを使って文字列を囲むことで実現しています。

en.wikipedia.org

例えば、文字列を赤くするためには以下のような文字列を標準出力に出力します(iTerm2想定)。

fmt.Println("\x1b[31;1mHello, World!\x1b[0m")

ターミナルは、上記エスケープコード付き文字列を「色つけの指示付きの文字列」と解釈してエスケープコード部分を省いて色をつけた形で表示します。

つまり、色をつけているのはターミナルです。

エスケープコードを解釈するのがターミナルでない場合(パイプにつなげたりリダイレクトでファイルに保存する場合)、エスケープコードは「ただの文字列として解釈されてしまう = 不必要な文字列がついている状態」となるわけです。

上記を回避するために grep --color ではターミナル(擬似端末)かどうかを判断してエスケープコードの出力を制御しているようです。grep --color=always はその判定処理をスキップしているわけですね。

ちなみに、擬似端末判定処理について、Golangだと github.com/mattn/go-isatty が有名だと思います。

github.com

colrは色をつけるツール

colr はシンプルに色をつけるためだけのツールです。色をつけなければ何もしないただリソースを消費するだけのコマンドになってしまいます。

なので、「 colr を利用するときは、どうしても色をつけたいのだろう」と考え、(利用カラーリングライブラリにはターミナル判定処理がついているのですが、)上記の擬似判定処理をスキップしています。

これで、どう使っても色がつくようになりました。

おすすめ

Goならわかるシステムプログラミング

Goならわかるシステムプログラミング