修正する

修正する

grepデフォルトでは、これらはsedすべて「基本正規表現」(「BRE」)を使用するものとして説明されます。 BREはこれをよく説明しています。ここ

ただし、次の出力を考慮してください。

# echo '    aaaaa   ' | grep '\(aaaaa\|bbbbb\)'
    aaaaa
# echo '    aaaaa   ' | sed '/\(aaaaa\|bbbbb\)/ s/ /_/g'
    aaaaa

最初のコマンドでは、構文\( ... \| ... \)明確な行動as (X OR Y)、出力が通過するためですgrep

2番目のコマンドで\( ... \| ... \)は、構文は何も行っていないようですas (X OR Y)、空白が下線に変わらないからです。

(逆に、両方\+「複数回繰り返される」と認識されるコマンド)

どうしたの? FreeBSDに2つのBREがあるように見えるのはなぜですか?そのうちの1つは構文を認識し、もう1つは認識しませんか?

より深い問題は、多くのプロジェクトがBREを使用して他のUNIXシリーズシステムへの移植性を提供することを望んでいることです。しかし、これはBREでさえもプラットフォーム間で同じである可能性がないことを示しています。以内に個人的なプラットフォーム。ああ?

答え1

リンクされた記事の説明が正しくありません。

実際のPOSIX定義指摘した:

エスケープされていない<バックスラッシュ>( '\')の前にある一般文字の解釈は定義されていません。[ (){}、数字、括弧内の表現]

一般文字は、.[^$*BRE特殊文字とバックスラッシュ自体を除くすべての文字として定義されます。

したがって、そのページの宣言とは異なり、\+BREは定義されていません\|

+|一部の正規表現実装では、これをERE、特にGNUと同じように定義します。ただし、それに依存してはならず、定義された機能に固執する必要があります。

もちろん、ここでの問題は、EREシフト演算子が|BREに存在せず、EREに対応する演算子が+非常に醜いということです\{1,\}。したがって、代わりにEREを使用することをお勧めします。

答え2

$ echo '    aaaaa   ' | sed 's/aaaaa|bbbbb/_/g'
    aaaaa
$ echo '    aaaaa   ' | sed -E 's/aaaaa|bbbbb/_/g'
    _
$ echo '    aaaaa   ' | sed -r 's/aaaaa|bbbbb/_/g'
    _
$ echo '    aaaaa   ' | sed -E '/(aaaaa|bbbbb)/ s/ /_/g'
____aaaaa___
$ echo '    aaaaa   ' | sed -E '/aaaaa|bbbbb/ s/ /_/g'
____aaaaa___

orBRE(基本正規表現)ではありません。-E指定する必要があります。拡大する着替える。

バラよりGNUまたはBSD Sedの正規表現置換/または演算子(foo | bar)

修正する

grepが機能する理由は何ですか?

使用したいモードを選択できます。grep

  -E, --extended-regexp     PATTERN is an extended regular expression
  -F, --fixed-strings       PATTERN is a set of newline-separated strings
  -G, --basic-regexp        PATTERN is a basic regular expression
  -P, --perl-regexp         PATTERN is a Perl regular expression
  -e, --regexp=PATTERN      use PATTERN as a regular expression

grepこれらのスイッチを使用すると、BREが実際にBREにデフォルト設定され、OP式がEREで失敗することを確認できます。

$ echo '    aaaaa   ' | grep '\(aaaaa\|bbbbb\)'
    aaaaa
$ echo '    aaaaa   ' | egrep '\(aaaaa\|bbbbb\)'
$ echo '    aaaaa   ' | grep -E '\(aaaaa\|bbbbb\)'
$ echo '    aaaaa   ' | grep -G '\(aaaaa\|bbbbb\)'
    aaaaa
$ echo '    aaaaa   ' | grep -G 'aaaaa\|bbbbb'
    aaaaa
$ echo '    aaaaa   ' | grep -G 'aaaaa|bbbbb'
$ echo '    aaaaa   ' | grep -E 'aaaaa|bbbbb'
    aaaaa
$ echo '    aaaaa   ' | grep -E 'aaaaa\|bbbbb'
$ echo '    aaaaa   ' | grep -G 'bbbbb\|aaaaa'
    aaaaa
$ echo '    aaaaa   ' | grep -E 'bbbbb\|aaaaa'
$ echo '    aaaaa   ' | grep -G 'bbbbb|aaaaa'
$ echo '    aaaaa   ' | grep -E 'bbbbb|aaaaa'
    aaaaa

両方grepそしてsed引用するリフォーマット(7)それは明らかに次のように言います:

未使用(「デフォルト」)正規表現はさまざまな点で異なります。 `|'は通常の文字であり、機能的に同等の文字はありません。

しかし、「パイプを脱出」すると機能が得られるようです。確かにそんなにおいがしますね。しかも最近コースが被害を受けたようです。regex(3): 最近の BRE 回帰に対処するためのテストを追加

代用できる職業もあると思います。正規表現libcから。

Charles Duffyが以下に述べたように

一部のツールは、バックスラッシュを使用してBREコンテキストでEREのみの動作を取得できる非標準拡張を実装しているためです。

私はFreeBSDの非常に素晴らしいドキュメントに精通しています。つまり、これが意図的でしたが文書化されていないのか、それとも破損しているのかはわかりません。

関連情報