全力で怠けたい

怠けるために全力を尽くしたいブログ。

Mac の sed とか tr が illegal byte sequence エラーになるときの回避方法のメモ。

Macsed とか tr が illegal byte sequence エラーになるときの回避方法のメモ。

sed とか tr が illegal byte sequence エラーになる

どんなことがおきるか

sed とか tr が illegal byte sequence エラーになってしまうことがある。

たとえば ascii 文字のうち英字と数字だけを表示するのをやってみるとこんな感じにエラーになる。 tr のほうはエラーメッセージを表示と一応は英数字を出力してるけど sed のほうは完全に沈黙してる感じ。

$ awk 'BEGIN{for(i=0;i<256;i++){printf("%c",i)}}' | tr -dc "[:alnum:]"
tr: Illegal byte sequence
0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz

$ awk 'BEGIN{for(i=0;i<256;i++){printf("%c",i)}}' | sed -E 's/[^a-zA-Z0-9]//g'

sed: RE error: illegal byte sequence

どうしたら回避できるか

こういうときは LC_CTYPE=C を指定して sed とか tr を実行すると illegal byte sequence エラーは回避できる。

$ awk 'BEGIN{for(i=0;i<256;i++){printf("%c",i)}}' | LC_CTYPE=C tr -dc "[:alnum:]"
0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz

$ awk 'BEGIN{for(i=0;i<256;i++){printf("%c",i)}}' | LC_CTYPE=C sed -E 's/[^a-zA-Z0-9]//g'

0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz

ただ LC_ALL が指定してあると LC_ALLLC_CTYPE より優先されるので LC_CTYPE=C を指定しても illegal byte sequence エラーになっちゃう。

$ locale | grep LC_ALL
LC_ALL="ja_JP.UTF-8"

$ awk 'BEGIN{for(i=0;i<256;i++){printf("%c",i)}}' | LC_CTYPE=C tr -dc "[:alnum:]"
tr: Illegal byte sequence
0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz

$ awk 'BEGIN{for(i=0;i<256;i++){printf("%c",i)}}' | LC_CTYPE=C sed -E 's/[^a-zA-Z0-9]//g'

sed: RE error: illegal byte sequence

LC_ALL が指定してあるときは LC_ALL=C を指定して sed とか tr を実行すると illegal byte sequence エラーを回避できる。

$ awk 'BEGIN{for(i=0;i<256;i++){printf("%c",i)}}' | LC_ALL=C tr -dc "[:print:]"
 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~

$ awk 'BEGIN{for(i=0;i<256;i++){printf("%c",i)}}' | LC_ALL=C sed -E 's/[^a-zA-Z0-9]//g'

0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz