macOSのsedでは色文字をフィルタする方法が使えない!?
おはようございます。長男は、最近さっさとドリルを終わらせて、ゲームにまっしぐら。車のレースゲームを 好んでやってます。そのゲームの中で見かけて気に入った車を一緒に作ってるゲームにも出せと言ってきて、週末はblenderで 色付けたり、ボディーとタイヤを分離するなどをやってる@kjunichiです。
背景
昨年以下の記事を書いた。
しかし、Goで出来たマストドンのライブラリ
を使ったクライアントでこの方法を使っても ターミナル(黒い画面)上には、色つきの文字が表示される。。。
ツイッタークライアントのtwのひみつ
twでは出力先がパイプの場合、文字に色を付けずに出力していたことを知った。 出力先が標準出力ではなく、パイプであるという情報がプログラム的に知ることができる模様。
以下のように、
tw @kjunichi/comp |od -xc
として、出力されるコードを確認したら、文字色の制御コードが含まれていなかった。
つまり、
tw @kjunichi/comp|cat
とするだけで、sedなどかまさずとも文字に色がつかずに表示されるのだった。
なぜgo-mastodonのクライアントの文字の色がついてしまうのか?
始めは、ANSIのカラー指定で拡張規格やらで、未知のコードを使用しているのかとも 疑うも、sedに指定している制御コード以外は見当たらない。
結局、macOSのsedがBSDだからということが判明した!
sed "s,$(printf '\033')\\[[0-9;]*[a-zA-Z],,g"
といった感じで直接制御コード値をコマンド引数に指定する必要があった。bashでは、以下の様に $'<文字列>'とすることで、制御コード値を出力させることも出来る模様。
sed $'s,\x1b\\[[0-9;]*[a-zA-Z],,g'
これが、GNUのsedではコマンドライン引数に文字列として「\x1b」が渡ってきてもこれを制御コードとして 処理をしてくれる為、文字の色が消せるのだった。
ちなみにHomebrewでGNU版のsedを入れることもでき、これは、gsedで呼び出すこと出来る。
brew install gnu-sed
参考資料
- https://unix.stackexchange.com/questions/140251/strip-color-on-os-x-with-bsd-sed-or-any-other-to
- http://www.atmarkit.co.jp/flinux/rensai/linuxtips/a018bashhexcode.html
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-mastodonのGithubに行ったら、だいぶ進化していた。 ストリームを表示するなどもコマンドラインから叩ける模様。
あんまり遭遇しないけど、たまぁにこういったUNIXコマンドのGNU版とBSD版の違いでハマることがあるので、 macOSはBSDベース(APPLEが公開してるソースを見るとFreeBSD由来っぽい)と言う事を覚えておいて損はないと思う。