POSIX Sed のスクリプトの構文等の仕様について

Published: 2021/5/13


https://pubs.opengroup.org/onlinepubs/9699919799/utilities/sed.html

上記は、 POSIX を策定している団体である Open Group の、 sed についてのページであるが、いかんせん長いので、これを分かりやすくまとめてみる。

invocation まわり

  • -e スクリプト で実行するスクリプトの末尾にその文字列を追記。次にスクリプトが追記されるときには、改行(\n)がその間に挿入される。
  • -f ファイル で実行するスクリプトの末尾にそのファイルの中身を追記

全体的な構文

<editing-command> ::= (<blank> | ";")* <addresses> <blank>* ["!"] <function>
<addresses> ::= [ <address> [ "," <address> ] ]
<address> ::= "$" | <number> | <BRE>

<function> ::= <simple-command> | <s-command> | <y-command> | <file-command>
               | <text-command> | <branching-command> | <label-def>
               | <compound-command>

<file-command> ::= ("r" | "w") <blank>+ <file-name>
<s-command> ::= "s" <sep> <BRE> <sep> <replacement> <sep> <s-single-flags>* [ "w" <blank>+ <file-name> ]
<y-command> ::= "y" <sep> <y-string> <sep> <y-string> <sep>
<text-command> ::= ("a" | "c" | "i") <backslash> <newline>
                   (<string-without-trailing-backslash> <backslash> <newline>)*
                   <string-without-trailing-backslash>
<branching-command> ::= ("b" | "t") " " <label>
<label-def> ::= ":" <label>

<compound-command> ::= "{" <editting-commands> "}"

ただし、

  • <BRE>/BRE/ もしくは \cBREc の形式で表される。
    • 後者の場合、\と改行文字以外であれば、cには何の文字でも利用可能。
    • 始端と終端を表す文字(以降、セパレータ)をBRE中で利用するためには、\でエスケープする。
    • 改行文字は \n で表される。
  • s, y コマンドで利用される <sep> は、そのコマンドの中で同一の文字であって、\ もしくは <newline> でなければ何でも良い。
    • s コマンドの <BRE><replacement>, y-string の中で<sep>を利用したい場合は、\でエスケープすることで利用可能。
  • <y-string> 中、改行文字は \n で表される。
  • s コマンドにおける <replacement> において、特殊扱いされる文字列は以下の通り
    • &: BREがマッチした文字全体に replace される
    • \1: 1番目のBREのグループ。以下2番, 3番以降も同様
    • 改行文字: \によってエスケープされる必要がある。改行文字自身に置換される。
  • <editting-commands> は改行文字もしくは;によって分割される。ただし、; は一部のシンプルのコマンドに対してしかセパレータとして機能しない。

補足として、<branching-command> において、コマンドとラベルの間のスペースは、実際どのような文字(列)がシングルスペース以外で許容されているのかは、仕様には記載されていない模様。

<blank> は locale によって指定される blank クラスの文字だと考えられる。

その他雑記

  • 2addr 形式の場合、まず最初の address にマッチすればその range はスタートし、2つめのアドレスにマッチしたとこで range が終了する。 range が終了した後は、また最初の address による range スタートの判定が始まる。 range は inclusive range である。

Tags: posixsed

関連記事