non vorrei lavorare

ブログ名の通りです。javascript three.js mruby rust OCaml golang julialang blender

macOSのsedでは色文字をフィルタする方法が使えない!?

おはようございます。長男は、最近さっさとドリルを終わらせて、ゲームにまっしぐら。車のレースゲームを 好んでやってます。そのゲームの中で見かけて気に入った車を一緒に作ってるゲームにも出せと言ってきて、週末はblenderで 色付けたり、ボディーとタイヤを分離するなどをやってるkjunichiです。

背景

昨年以下の記事を書いた。

abrakatabura.hatenablog.com

しかし、Goで出来たマストドンのライブラリ

github.com

を使ったクライアントでこの方法を使っても ターミナル(黒い画面)上には、色つきの文字が表示される。。。

ツイッタークライアントのtwのひみつ

twでは出力先がパイプの場合、文字に色を付けずに出力していたことを知った。 出力先が標準出力ではなく、パイプであるという情報がプログラム的に知ることができる模様。

以下のように、

tw @kjunichi/comp |od -xc

として、出力されるコードを確認したら、文字色の制御コードが含まれていなかった。

つまり、

tw @kjunichi/comp|cat

とするだけで、sedなどかまさずとも文字に色がつかずに表示されるのだった。

なぜgo-mastodonのクライアントの文字の色がついてしまうのか?

始めは、ANSIのカラー指定で拡張規格やらで、未知のコードを使用しているのかとも 疑うも、sedに指定している制御コード以外は見当たらない。

結局、macOSsedBSDだからということが判明した!

sed "s,$(printf '\033')\\[[0-9;]*[a-zA-Z],,g"

といった感じで直接制御コード値をコマンド引数に指定する必要があった。bashでは、以下の様に $'<文字列>'とすることで、制御コード値を出力させることも出来る模様。

sed $'s,\x1b\\[[0-9;]*[a-zA-Z],,g'

これが、GNUsedではコマンドライン引数に文字列として「\x1b」が渡ってきてもこれを制御コードとして 処理をしてくれる為、文字の色が消せるのだった。

ちなみにHomebrewでGNU版のsedを入れることもでき、これは、gsedで呼び出すこと出来る。

brew install gnu-sed

参考資料

go-mastodonのクライアントのソース

色付きの文字を出している該当箇所

//時刻:アカウント名:メッセージを色つけて表示する
fmt.Printf("\x1b[37m[%s] \x1b[35m%-20s: \x1b[33m%s\n", t.Status.CreatedAt.Local().Format("15:04:05"), t.Status.Account.Acct, t.Status.Content)
//色に関してはこちらを参考 http://misc.flogisoft.com/bash/tip_colors_and_formatting

おわりに

記事を書くにあたり、久しぶりにgo-mastodonGithubに行ったら、だいぶ進化していた。 ストリームを表示するなどもコマンドラインから叩ける模様。

あんまり遭遇しないけど、たまぁにこういったUNIXコマンドのGNU版とBSD版の違いでハマることがあるので、 macOSBSDベース(APPLEが公開してるソースを見るとFreeBSD由来っぽい)と言う事を覚えておいて損はないと思う。

関連記事