Macのgrepでgrep: empty (sub)expressionと出る場合の対処法

1 min read読了の目安(約1300字
  • Macを利用して業務や趣味でgrepをかけて検索や集計等を行うことが多い。
  • その際に表題の通りのエラーに遭遇する場合がある。
  • そのため今回は、このエラーが出た時の対処法を2点記録する。

結論

  • 方法としては以下の2点。※先をお急ぎの方はGNU版導入を推奨。

    • brew install grepでGNU版のgrepを導入。
      • ※Mac標準のgrepはBSD版。
    • BSDでも動作するようなgrepの書き方に修正する。
  • ※詳細内容は以下の内容蘭で説明。

環境

  • Mac OS X 10.15.6
  • Darwin 19.6.0

内容

エラー元

  • エラーは以下のような例で起きます。
# 文字列の中から、Hello or World or 空 かを検索する。
echo -e "Hello\nWorld" | grep -E '(Hello|World|)'

# エラー出力
grep: empty (sub)expression

原因

  • 原因として、以下が考えられます。
    • 正規表現での検索で、候補に空を加えている。
    • GNUとBSD版で細かな挙動が違うと耳に入ったことがある。
  • 検証のため、Dockerで用意したGNU grep環境で検証したところ、上記の書き方でも問題は無かった。
  • このことから空選択時の処理で、細かな挙動の違いが原因であるとわかった。

解消

  • 原因特定のため、以下の2点の方法で解消する。
    • GNU版grepをインストールする。
    • BSDでも動作するようなgrepの書き方に修正する
  • 1つ目のGNU版は以下のコマンドをうつだけで完了。
    • brew install grep
  • 2つ目は、以下のように空選択時の処理を変更する。
# 行頭・行末の記号で認識させる。
echo -e "Hello\World" | grep -E '(^|Hello|World)'

# 空選択処理自体を削除。
echo -e "Hello\nWorld" | grep -E '(Hello|World)'
  • ※空選択は、両方のやり方に一長一短があるため、無難の方を選択

まとめ

  • 上記のことから、各OS・ライブラリによっての細かな挙動の違いを認識。
  • そのため可搬性の高い記述を意識。

参考