Macのsedで使える正規表現はPOSIX BRE(Basic Regular Expressions)

コンピュータ関連
スポンサーリンク

さて、
先日どハマりしたsed(文字列置き換え)コマンドでの正規表現。

困ったことに・・・
なんだかよくわからないけど・・・
ネットにおいてあるサンプルが動かないのですよ!

マニュアルを表示させて見てもなんか要領を得ないし・・・

スポンサーリンク

Macで使えるのはBSD sed?

一応環境としてはmacOS 10.13 High Sierra でのお話です

結論から言うとmacに入っている sed は古い!(たぶん)

バージョンを確かめるオプションがないので調べることもできません。
(知ったところで出来ることもありませんが(^^;))

とりあえず一生懸命マニュアルを読んで見たものの、
そこにいろいろ記述はあれど期待したようには動いてくれないのです。

そして一番最後にあった日付が・・・なんと

Sept 29, 2011

今は2020年なので・・・ねぇ。

もちろんマニュアルの日付が”直接コマンドの新旧に結びつくわけではない”のですが、
ネットで調べると「GNU sedがバージョンアップした」だの何だのと書いてあるわけですよ。

で、調べていくうちに何となくわかったのが
macOSに入っているのは「BSD系 sed」だということ。

そして「POSIX BRE(Basic Regular Expressions:基本正規表現)」という、
かなり基本的、かつ限られた表現のみが使えるということ。

一回以上の繰り返しにマッチする「+」や、
数字を表す「\d」、空白文字を表す「\s」やらは使えないのです。

何てこったい(絵文字略

スポンサーリンク

ERE(extended REs)のオプション指定

ただ -E オプションを使うことで「ERE(extended REs)」が使えるようになるようです。

   SED(1)                    BSD General Commands Manual
   ...

   -E    Interpret regular expressions as extended (modern) regular expressions rather than
 basic regular expressions (BRE's).  The re_format(7) manual page fully describes both formats.

そして 詳細が書いてあるという re_format(7) manual ページを読んでみると

   re_format -- POSIX 1003.2 regular expressions
   ...

   Shortcuts (available for both enhanced basic and enhanced extended REs)
     The following shortcuts can be used to replace more complicated bracket
     expressions.

           \d  Matches a digit character.  This is equivalent to
               `[[:digit:]]'.

           \D  Matches a non-digit character.  This is equivalent to
               `[^[:digit:]]'.

           \s  Matches a space character.  This is equivalent to
               `[[:space:]]'.
   ...

およ?「\d」とか使えるの?
と思ったけどそうは問屋が卸さない。

結論から言うと使えませんでした。(マニュアルに書いてあるのに!)

キャラクタクラス(e.g. `[[:digit:]]’)の方は元から使えるので大丈夫です。
まぁ数字に関しては [0-9] も使えるから…いいけど。

でもなんだかなぁ。

スポンサーリンク

POSIX 1003.2での正規表現

引用します。

POSIX 1003.2では、二種類の正規表現 Basic Regular Expression (以下BRE)と Extended Reuglar Exression(以下ERE)が定められています。 BREを使用するユーティリティには、ed, ex, vi, more, sed, grepなど、 EREを使用するユーティリティには awk, egrep があります。 Regular Expressoionsや POSIX 1003.2 regular expressionsに説明があります。

BRE で使える正規表現演算子(メタキャラクタ)は以下の通りです。

  • [=char=]
  • [:classname:]
  • [.char-seq.]
  • [char-list]
  • \(regexp\)
  • *
  • \{n,m\}
  • \{n\}
  • \{n,\}
  • ^
  • $
  • .

EREで使える正規表現演算子(メタキャラクタ)は以下の通りです。

  • [=char=]
  • [:classname:]
  • [.char-seq.]
  • [char-list]
  • (regexp)
  • *
  • +
  • ?
  • {n,m}
  • {n}
  • {n,}
  • ^
  • $
  • |
  • .

正規表現メモより一部引用)

割と少ないですね。
そして前述の通り「\s」や「\d」なんかは含まれていません。

ただ -E オプションを使うことでEREが有効になり、「+」「?」「|」なんかは使えるようになります。
詳しくは引用元のサイトで確認して見てください。

ところで、-E オプションを使わないと繰り返しの「\{1,\}」も動かないのは何故なんでしょうか・・・
BREに含まれているはずなんですけど。
そしてオプションをつけることで「+」(バックスラッシュをつけて \+ )が有効になり、n回の繰り返し指定も使えるようになる、と。
なんでやねん。

スポンサーリンク

まとめ

ということで、マニュアルに書いてあるからって鵜呑みにしちゃいけないよ♪テヘッ
というお話でした。違うか。

要するに
BRE(Basic Regular Expressions)またはERE(extended REs)で使える表現で書きましょう!
ということのようでした。

ちなみに homebrew から「GNU sed」をインストールして使うこともできるようです。

ただそれを前提としてスクリプトを書いてしまうと読んだ方が
「動かんやないかぁ!」と今回の自分みたいになるわけで、ちと微妙です。

そもそも詳しい人はググってこんな記事とか読まないわけで、
やりたいことの前によくわからんコマンドをインストールさせられるなんて・・・自分なら他行くわ。(苦笑

しかしマニュアル読んでも違うし、ネットで探せばLinuxの方と情報がごっちゃになるし、
なかなか難しいですな。

この記事が同じような悩みを抱えた方のヒントになれば幸いです。
では。

コメント

タイトルとURLをコピーしました