![GNU sed --posix および置換文字列内の改行文字](https://rvso.com/image/168813/GNU%20sed%20--posix%20%E3%81%8A%E3%82%88%E3%81%B3%E7%BD%AE%E6%8F%9B%E6%96%87%E5%AD%97%E5%88%97%E5%86%85%E3%81%AE%E6%94%B9%E8%A1%8C%E6%96%87%E5%AD%97.png)
POSIXsed
仕様ではこの文見つけることができる(強調は筆者による):
エスケープ シーケンス '\n' は、パターン スペースに埋め込まれた <newline> と一致します。リテラル<改行>は使用してはならないコンテキストアドレスのBREまたは代替機能で。
フラグ付きの次の GNUsed
コマンドは--posix
、置換関数で改行が使用されているため、その仕様に反しています。
$ printf '1X2' | sed --posix 's|X|\n|'
1
2
では、なぜsed
エラー メッセージを表示する代わりに改行を挿入したのでしょうか?
答え1
「リテラル <newline> は使用しないでください」、例ではリテラルの改行は使用されていません。したがって、標準のこの部分は関係ありません。
\n
はない文字通りの改行。
答え2
この--posix
フラグにより、GNU sed
POSIX に準拠します。
POSIX では動作はs/x/\n/
未指定のままです:
エスケープされていない <バックスラッシュ> の直後に '&'、<バックスラッシュ>、数字、<改行>、またはこのコマンドに使用される区切り文字以外の文字が続く場合の意味は指定されていません。
したがって、x
を に置き換えn
、 を に\n
置き換え、改行し、エラーを報告し、コンピュータを再起動することは、すべて準拠した動作です。GNU がsed
そこで動作を変更したい理由はありません。
適合する応用(つまり、その場合はスクリプト) は\n
そこで使用しないでください。引用したテキストはそれに関するものです。
s/[\t]/x/g
POSIX では\
とt
の両方を に置き換えることが要求されている点で異なり、そこで GNU の動作が によって変更されることx
がわかります。 については、POSIX 仕様は実際にはあいまいです。 GNU はでの動作を変更して とをに置き換えますが、それが必要なのかどうかはそれほど明確ではありません。sed
--posix
s/[\n]/x/g
sed
--posix
\
n
x
答え3
この規格では、検索パターン(BRE、POSIX用語で言えば基本正規表現)明示的な改行は使用できず、改行は'\n'で表され、交換どちらか。
検索パターンには、明示的または '\n' で表される改行が含まれていません。置換に '\n' があります。上記では、置換テキストで改行がどのように表現されるか (表現される場合) は示されていません。GNU sed は、前述を '\n' で置換すると改行が導入されることを意味すると解釈します。理にかなっています。