6.3 複数行を扱う手法:D,G,H,N,Pによる複数行の処理

D、G、H、N、Pを使うと、複数行を1つのバッファーとして処理できます。これらは対応する小文字のコマンド(d、g、h、n、p)と似ていますが、バッファー内の改行を考慮しながらデータを追加・削除する点が異なります。そのため、パターンスペースやホールドスペースの行を追加・削除できます。

動作は次のとおりです。

D

パターンスペースの最初の改行までの行を削除し、サイクルを再開します。

G

ホールドスペースの行を、先頭に改行を付けてパターンスペースへ追加します。

H

パターンスペースの行を、先頭に改行を付けてホールドスペースへ追加します。

N

入力ファイルの行をパターンスペースへ追加します。

P

パターンスペースの最初の改行までの行を表示します。

次の例は、NとDコマンドの動作を示します。

$ seq 6 | sed -n 'N;l;D'
1\n2$
2\n3$
3\n4$
4\n5$
5\n6$
  1. sedは、まず最初の行をパターンスペースへ読み込みます(つまり「1」です)。
  2. 各サイクルの開始時に、Nコマンドが改行と次の行をパターンスペースへ追加します(最初のサイクルでは「1」「\n」「2」です)。
  3. lコマンドは、パターンスペースの内容を曖昧さのない形式で表示します。
  4. その後、Dコマンドがパターンスペースの最初の改行までの内容を取り除きます(最初のサイクルの末尾では「2」が残ります)。
  5. 次のサイクルでは、Nコマンドが改行と次の入力行をパターンスペースへ追加します(たとえば「2」「\n」「3」です)。

行ごとに処理する代わりに、段落のようなテキストのまとまりを処理する一般的な手法では、次の構文を使います。

sed '/./{H;$!d} ; x ; s/REGEXP/REPLACEMENT/'
  1. 最初の式/./{H;$!d}は、空でないすべての行に対して動作し、現在の行(パターンスペース内の行)をホールドスペースへ追加します。最後の行を除くすべての行では、パターンスペースを消去してサイクルを再開します。
  2. 残りの式xとsは、空行(つまり段落の区切り)に対してだけ実行されます。xコマンドは、ホールドスペースに蓄積した行をパターンスペースへ戻します。その後、s///コマンドが段落内のすべてのテキスト(内部の改行を含む)に対して動作します。

次の例は、この手法を示します。

$ cat input.txt
a a a aa aaa
aaaa aaaa aa
aaaa aaa aaa

bbbb bbb bbb
bb bb bbb bb
bbbbbbbb bbb

ccc ccc cccc
cccc ccccc c
cc cc cc cc

$ sed '/./{H;$!d} ; x ; s/^/\nSTART-->/ ; s/$/\n<--END/' input.txt

START-->
a a a aa aaa
aaaa aaaa aa
aaaa aaa aaa
<--END

START-->
bbbb bbb bbb
bb bb bbb bb
bbbbbbbb bbb
<--END

START-->
ccc ccc cccc
cccc ccccc c
cc cc cc cc
<--END

注釈付きの例については、複数行にまたがるテキスト検索と行長の調整も参照してください。