Bash

エスケープされた日本語文字列を読みたい

More than 5 years have passed since last update.

ちょっとした日本語出力がエスケープコードになってイラッとすることがある。

そのたびにツールをさがしたり変換スクリプトを書いてしのいできたが

実はコマンドの echo -e や printf で手間なしでデコードできることを最近知った。

$ echo -e '\xe3\x82\xa8\xe3\x83\xa9\xe3\x83\xbc'

エラー

ただし環境によりでサポートに違いがあるので注意が必要。


$ /usr/bin/printf '\xef\xbc\x91\xef\xbc\x96\xe9\x80\xb2\xe6\x95\xb0 \357\274\230\351\200\262\346\225\260 \u30e6\u30cb\u30b3\u30fc\u30c9 \n'
16進数 8進数 ユニコード

$ printf '\xef\xbc\x91\xef\xbc\x96\xe9\x80\xb2\xe6\x95\xb0 \357\274\230\351\200\262\346\225\260 \u30e6\u30cb\u30b3\u30fc\u30c9 \n'
16進数 8進数 \u30e6\u30cb\u30b3\u30fc\u30c9

$ /bin/echo -e '\xef\xbc\x91\xef\xbc\x96\xe9\x80\xb2\xe6\x95\xb0 \357\274\230\351\200\262\346\225\260 \u30e6\u30cb\u30b3\u30fc\u30c9'
16進数 8進数 \u30e6\u30cb\u30b3\u30fc\u30c9

$ echo -e '\xef\xbc\x91\xef\xbc\x96\xe9\x80\xb2\xe6\x95\xb0 \357\274\230\351\200\262\346\225\260 \u30e6\u30cb\u30b3\u30fc\u30c9'
16進数 \357\274\230\351\200\262\346\225\260 \u30e6\u30cb\u30b3\u30fc\u30c9

上記は CentOS6.5 環境で試した例だが、まず bash の組み込みか、外部コマンドかで挙動が違う。

また他の環境でも試したが、サポート状況にばらつきあった。

マニュアルの記述もあてにならないので、今の環境でなにが変換できるかは実際に試してみるしかない。

ここで、よく見かける形式の例として


  • \xHH 16進数。
    PHP で日本語メッセージを trigger_error() すると Apache の error_log にこの形式で出力される。

  • \nnn 8進数。
    Ruby でみかける。

  • \uHHHH ユニコードの16進表現
    Java のプロパティーファイル(properties) 。

もし文字化けしたら、それは文字コードの問題なので nkf などでさらに変換すれば読めるはず。

シェル関数かエイリアスでフィルタにしておくと便利かも。

$ alias unesc='while read -r a; do /usr/bin/printf "$a\n" ; done'

$ tail -f error_log | unesc | grep 'エラー'
[Thu Jan 02 22:43:39 2014] [error] [client 192.168.56.1] PHP Notice: 妄想エラーです in /var/www/html/trigger_error.php on line 3