このsedコマンドが一番下の3番目の「and」を置き換えないのはなぜですか?

このsedコマンドが一番下の3番目の「and」を置き換えないのはなぜですか?

2020年5月26日更新

これがバグのようで、バグを報告しました。 IDは#41558です。


私はただ遊び心があり、sed次の練習を思いついた。 「and」(サブストリングではなく単語)の最後から3番目の項目を置き換えて生成します。

dog XYZ foo and bar and baz land good

私はこれがうまくいくと思いました。

echo 'dog and foo and bar and baz land good' |
    sed -E 's/(.*)\band\b((.*\band\b){2})/\1XYZ\2/'

しかし、実際には「and」の終わりに2番目の発生を置き換えます。私が考えることができる唯一の説明は、そのうちの1つに「土地」が含まれているということですが、「境界」という単語を\band\b含めたので、そうすべきではないか?\b

ベストアンサー1

sedこれは、PCREでサポートされているようにツアーなどがサポートされていないため、実行するのは難しいです。文字列を逆にして、最初から3番目に出てくる反転された単語を変えてから、もう一度置き換える方が簡単です。

$ echo 'dog and foo and bar and baz land good' | rev | sed 's/\<dna\>/XXX/3' | rev
dog XXX foo and bar and baz land good

表現がうまくいかない理由はバグのようです。逆参照は、以前の内容がまったく影響を与えていないかのように\3文字列のようです。 baz land\band.*\band\b

注文する

sed -E 's/(.*)\<and\>((.*\<and\>){2})/\1XYZ\2/'

sedOpenBSDでは、基本的に正しい操作を実行しているようです(使用\<\>交換)。\b

sed私はGNUまたはGNUの既存のバグレポートを見つけることができませんでしたglibc。少なくともそれでも驚かないでしょう。関連到着glibcエラー25322(なぜなら以下を参照してください)。

この問題をさらに詳しく解決できます。

sed -E 's/(.*)\band\b(.*\band\b.*\band\b)/\1XYZ\2/'

おすすめ記事