このページの内容

4.3 テキストの一致による行の選択

GNU sed は、次の正規表現アドレスをサポートします。既定の正規表現は基本正規表現(BRE)です。-E または -r オプションを使う場合、正規表現は拡張正規表現(ERE)の構文で記述してください。基本正規表現(BRE)と拡張正規表現(ERE)を参照してください。

/regexp/

正規表現 regexp に一致する行を選びます。regexp 自体に / 文字を含める場合、それぞれをバックスラッシュ(\)でエスケープしてください。

次のコマンドは、「bash」で終わる /etc/passwd 内の行を表示します5。

sed -n '/bash$/p' /etc/passwd

空の正規表現「//」は、最後の正規表現による一致処理を繰り返します(s コマンドに空の正規表現を渡した場合も同じです)。正規表現の修飾子は正規表現のコンパイル時に評価されるため、空の正規表現と一緒に指定することはできません。

\%regexp%

(% は、ほかの任意の1文字に置き換えられます。)

これも正規表現 regexp に一致しますが、/ とは異なる区切り文字を使えます。regexp 自体に多くのスラッシュが含まれる場合は、すべての / をエスケープする手間を省けるため、特に便利です。regexp 自体に区切り文字を含める場合、それぞれをバックスラッシュ(\)でエスケープしてください。

次のコマンドは同じ意味で、「/home/alice/documents/」で始まる行を表示します。

sed -n '/^\/home\/alice\/documents\//p'
sed -n '\%^/home/alice/documents/%p'
sed -n '\;^/home/alice/documents/;p'
/regexp/I
\%regexp%I

正規表現の一致処理に付ける I 修飾子は GNU 拡張で、regexp を大文字・小文字を区別せずに照合します。

ほかの多くのプログラミング言語では、大文字・小文字を区別しない正規表現の照合に小文字の i を使います。しかし、sed では i は挿入コマンドとして使います(挿入コマンドを参照)。

次の例の違いに注目してください。

この例では、/b/I がアドレスで、I 修飾子を付けた正規表現です。d は削除コマンドです。

$ printf "%s\n" a b c | sed '/b/Id'
a
c

こちらでは、/b/ がアドレスで、正規表現です。i は挿入コマンド、d は挿入する値です。そのため、一致した行の上に「d」という行を挿入します。

$ printf "%s\n" a b c | sed '/b/id'
a
d
b
c
/regexp/M
\%regexp%M

正規表現の一致処理に付ける M 修飾子は GNU sed の拡張で、GNU sed に正規表現を複数行モードで照合させます。この修飾子を付けると、通常の動作に加えて、^ は改行の直後の空文字列に、$ は改行の直前の空文字列にそれぞれ一致します。特殊な文字列(\` と \')は、常にバッファーの先頭または末尾に一致します。また、複数行モードではピリオド文字は改行文字に一致しません。

正規表現アドレスは、現在のパターンスペースの内容に対して動作します。パターンスペースが変更された場合(たとえば s/// コマンドによって)、正規表現の照合は変更後のテキストに対して動作します。

次の例では、-n で自動表示を無効にしています。s/2/X/ コマンドは、「2」を含む行を「X」に変更します。/[0-9]/p コマンドは、数字を含む行に一致して表示します。2行目は /[0-9]/ の正規表現より前に変更されるため、一致せず、表示されません。

$ seq 3 | sed -n 's/2/X/ ; /[0-9]/p'
1
3

(5)

もちろん、同じことを行う方法はほかにも多数あります。たとえば、次のような方法です。

grep 'bash$' /etc/passwd
awk -F: '$7 == "/bin/bash"' /etc/passwd