LoginSignup
32

More than 5 years have passed since last update.

全角文字をsedやAWKの正規表現にかけると……

Last updated at Posted at 2014-09-08

気が利いてるのか、お節介なのか

ロケール環境変数(LC_*LANG)を認識してくれるGNU版のgrepやsed、AWKコマンドの正規表現は、キャラクタークラスを用いた場合、全角の文字を半角で対応する文字と同一視してくれます。

知ってました?

それを知らずにハマったことのある人には、「なんてお節介な!」と思える機能かもしれませんが、知っていれば便利な機能です。

[[:alnum:]]で試してみる

正規表現にはキャラクタークラス指定というものがあります。例えば[[:alnum:]]は、アルファベットと数字にマッチするクラスです。

UTF-8やEUC-JPなど、マルチバイト文字に対応するようにロケール環境変数が設定されていると、sedAWKにおける[[:alnum:]]は全角文字にも反応します。

$ echo 'MSX MSX2 MSX2+' | sed 's/[[:alnum:]]/*/g'
*** **** ****$ echo 'MSX MSX2 MSX2+' | awk '{gsub(/[[:alnum:]]/,"*");print}'
*** **** ****$ 

というように、行頭にある半角の“MSX”もその後に続く全角の“MSX2”も*に置換されます。

ちなみに、[]の中に^を付ければ意味が反転するわけですが、それもちゃんと効きます。やってみましょう。

$ echo 'MSX MSX2 MSX2+' | sed 's/[^[:alnum:]]/*/g'
MSX*MSX2*MSX2*
$ echo 'MSX MSX2 MSX2+' | awk '{gsub(/[^[:alnum:]]/,"*");print}'
MSX*MSX2*MSX2*
$ 

というわけで、アルファベットでも数字でもない、全半角スペースとプラス記号が*に置換されました。

[[:blank:]]で試してみる

もちろん他のキャラクタークラスでも同様です。例えば、半角スペースやタブに反応する[[:blank:]]というクラスでやってみましょう。

$ echo 'MSX MSX2 MSX2+' | sed 's/[[:blank:]]/*/g'
MSX*MSX2*MSX2+
$ echo 'MSX MSX2 MSX2+' | awk '{gsub(/[[:alnum:]]/,"*");print}'
MSX*MSX2*MSX2+
$ 

というように、行頭から4文字目の半角スペースもそれ以降にある全角スペースも*に置換されました。つまり、全角スペースも半角スペースも同一視されていることがわかります。

ですが、AWKのフィールド区切りは飽くまで半角のみなようで、上記文字列の最大フィールド番号(NF)を確認してみると2だったりします。

$ echo 'MSX MSX2 MSX2+' | awk '{print NF}'
2
$ 

へんなのー。

全角に反応させたくない場合はどうすればいいのか

全角と半角を区別し、半角だけにマッチしたいという場合も当然ありますよね。そういう場合は、環境変数を無効にしてやればOKです。

例えばenvコマンドに-iオプションを付けてその後にコマンドを書いてやれば、ロケールを含めて全ての環境変数が渡されなくなりますので全角文字はマルチバイト列と見なされて反応しなくなります。

$ echo 'MSX MSX2 MSX2+' | env -i sed 's/[[:alnum:]]/*/g'
*** MSX2 MSX2+
$ echo 'MSX MSX2 MSX2+' | env -i awk '{gsub(/[[:alnum:]]/,"*");print}'
*** MSX2 MSX2+
$ 

あるいは、環境変数LANGCにしたり、unsetしたりしてもいいです。

$ echo 'MSX MSX2 MSX2+' | LANG=C sed 's/[[:alnum:]]/*/g'
*** MSX2 MSX2+
$ unset LANG
$ echo 'MSX MSX2 MSX2+' | awk '{gsub(/[[:alnum:]]/,"*");print}'
*** MSX2 MSX2+
$ 

都合よく使い分けましょう。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
32