ストリームエディタ sed

目次

GNU sed

This file documents version 4.7 of GNU sed, a stream editor.

Copyright © 1998-2018 Free Software Foundation, Inc.

Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the section entitled “GNU Free Documentation License”.


1 はじめに

sedはストリームエディタです。ストリームエディタは入力ストリーム(ファイルやパイプラインからの入力)に対して基本的なテキスト変換を実行します。(edのような)スクリプトの編集を許可するエディタに似ていますが、sedは入力を1passで処理するので、より効率的です。しかしsedがパイプラインでテキストをフィルタ処理できる点は、他のタイプのエディタとの明確な違いです。


2 sedの実行

この章ではsedの実行方法について説明します。sedスクリプトの詳細や、独特なsedコマンド達については次章で取り扱います。


2.1 概要

通常sedは次のように起動します。

sed SCRIPT INPUTFILE...

例えばinput.txtファイル内にある全ての‘hello’ を‘world’ に置き換えるには次のようにします。

sed 's/hello/world/' input.txt > output.txt

INPUTFILE(入力ファイル)が指定されないか、または, '-'と指定されたときはsedは標準入力より入力します。次の3つは等価です。

sed 's/hello/world/' input.txt > output.txt
sed 's/hello/world/' < input.txt > output.txt
cat input.txt | sed 's/hello/world/' - > output.txt

通常sedは標準出力に出力します。-iコマンドラインオプションを指定すると、標準出力の代わりに、コマンドラインで指定した入力ファイル自身を編集します。そして、'W'コマンドや's///w'コマンド(wフラグ付き)は指定の他のファイルに書き出します。次のコマンドはfile.txtを書き換え、そして一切(標準出力に)出力しません。

sed -i 's/hello/world/' file.txt

デフォルトではsedは( ' d'コマンド等によって変更・削除されない限り)、入力処理した全てをプリントします。-n コマンドラインオプションは出力を抑制し、'p'コマンドは指定の行をプリントします。次のコマンドは入力の45行目だけをプリントします。

sed -n '45p' file.txt

sedは複数の入力ファイルを1つの長いストリームとして扱います。次の例は最初のファイル(one.txt)の最初の行をプリントし、そして最後のファイル(three.txt)の最後の行をプリントします。-s、--separate コマンドラインオプションを使うと逆にファイル単位で扱います。

sed -n  '1p ; $p' one.txt two.txt three.txt

'-e'や'-f'コマンドオプション無しだとsedは最初のコマンドラインオプションでない('-','--'で始まっていない)コマンドラインパラメータをスクリプトとして使い、それ以降のコマンドラインオプションでないコマンドラインパラメーター達を入力ファイル達として使います。'-e'や'-f'コマンドラインオプションがスクリプト指定の為に使われると、全てのコマンドオプションでないコマンドラインパラメータが入力ファイル群として使われます。'-e'や'-f'コマンドラインオプションは混在かつ複数回記述することができ、実行されるスクリプトはそれぞれのスクリプトをそのコマンドラインオプションの順番どおりに連結したものになります。

以下の3つは等価です。

sed 's/hello/world/' input.txt > output.txt

sed -e 's/hello/world/' input.txt > output.txt
sed --expression='s/hello/world/' input.txt > output.txt

echo 's/hello/world/' > myscript.sed
sed -f myscript.sed input.txt > output.txt
sed --file=myscript.sed input.txt > output.txt

2.2 コマンドラインオプション

sedを起動する完全な書式は次の通りです。

sed OPTIONS... [SCRIPT] [INPUTFILE...]

sedは以下のコマンドラインオプション達とともに起動することができます。

--version

起動したsed自身のバージョンと著作権表示をプリント次第終了します。

--help

これらコマンドラインオプション達の短く要約した使い方とバグ報告先をプリント次第終了します。

-n
--quiet
--silent

デフォルトではsedはスクリプトを実行し、各サイクルが終わるとパターンスペースの内容をプリントします(「sedはどのように動くか 」参照)。これらのコマンドラインオプションは各サイクル終了時の自動プリントを無効にし、その際sedは'p'コマンドで明示的に指示された場合のみプリントします。

--debug

(v 4.6)入力されたプログラムを標準形式でプリントし、注釈付きで実行します。

$ echo 1 | sed '\%1%s21232'
3

$ echo 1 | sed --debug '\%1%s21232'
SED PROGRAM:
  /1/ s/1/3/
INPUT:   'STDIN' line 1
PATTERN: 1
COMMAND: /1/ s/1/3/
PATTERN: 3
END-OF-CYCLE:
3
-e script
--expression=script

指定のスクリプトを実行(予定の)コマンドに追加します。

-f script-file
--file=script-file

スクリプトファイルで指定されるファイルの内容を実行(予定の)コマンドに追加します。

-i[SUFFIX]
--in-place[=SUFFIX],

このコマンドラインオプションはコマンドラインパラメータで指定した入力ファイルを直接書き換えます。そのために、GNU sed はテンポラリファイルを作り、標準出力ではなくこのテンポラリファイルに出力します。1

このオプションは'-s'、--separate コマンドラインオプションの動作もします。

ファイルのEOFに到達すると、テンポラリファイルは入力ファイルに上書きされます。もしこのコマンドラインオプションのパラメータとして拡張子が与えられていれば、テンポラリファイルを入力ファイル名にリネームする前に、入力ファイル名を変更します。これによりバックアップコピー2)が作成されます。

拡張子が'*'(アスタリスク)を含んでない場合は、拡張子を現在のファイル名の末尾に接尾辞(サフィックス)として追加します。拡張子が1つ以上の'*'(アスタリスク)を含んでいる場合は、拡張子の中の各'*'を現在のファイル名に置換したものをバックアップファイル名とします。これにより、接尾辞(サフィックス)の代わりに(またはそれに加えて)バックアップファイルに接頭辞(プレフィックス)を追加したり、元のファイルのバックアップコピーを別のディレクトリに配置することができます(ディレクトリが既に存在する場合)。

拡張子が与えられない時はバックアップを作ること無しに入力ファイルは上書きされます。

注意:短いオプションである'-i'コマンドラインオプションは引数を取るので、これに他の短いコマンドラインオプション文字を続けて書いてはいけません。

sed -Ei '...' FILE

これは -E -i と同じです。拡張子の指定が無いのでバックアップファイルは作成されず、FILEが直接書き換えられます。

sed -iE '...' FILE

これは --in-place=E と等価です。入力ファイル FILE のバックアップとして FILEE が作られます。

警告:-n-i を一緒に使用すると、前者は行の自動プリントを無効にし、そして、後者はバックアップ無しにファイルの内容を変更します。よって不用意に(明示的な'p’コマンドを無しで)使われると、ファイルの中身を空にしてしまいます。

# 間違った使用法: 'FILE'は切り捨てられます。
sed -ni 's/foo/bar/' FILE
-l N
--line-length=N

'l' sedコマンドで行を折り返すデフォルトの長さを指定します。長さに 0 (ゼロ)を指定すると折り返ししなくなります。指定が無い場合は70です。

--posix

GNU sedはPOSIX sedに数々の拡張を加えています。移植性のあるスクリプトの作成を簡単にする為に、このオプションはGNU sedで追加されたコマンド含めこの文書に述べられている全てのGNU sed拡張を無効にします。ほとんどの拡張機能はPOSIXで強制される文法外のsed プログラムを受け付けますが、それらのいくつかは(バグレポートで説明している'N'コマンドのような振る舞いは)実際には規格を破っています。GNU 拡張を無効にしたい場合は環境変数 POSIXLY_CORRECT に空で無い値をセットして下さい。

-b
--binary

このコマンドラインオプションは全てのプラットフォームで有効ですが、効果があるのはテキストファイルとバイナリファイルを区別するオペレーティングシステムだけです。そのように区別される—MS-DOS、Windows、Cygwinのような—オペレーティングシステムではテキストファイルはキャリッジリターン(CR;\x0d)ラインフィード(LF;\x0a)で区切られた行で構成され、sedは終わりのCRを通常の1文字扱いするのではなく無視するという特殊動作をします。このオプションが指定されるとsedは入力ファイルをバイナリモードで開きます。 つまり、sedはこの特殊動作をせず、単純に行はラインフィード(LF;\x0a)で終了するとして動作します。

--follow-symlinks

このコマンドラインオプションが有効なのプラットフォームがシンボリックリンクをサポートしていて、かつ、'-i'コマンドラインオプションが指定された時だけです。この場合、コマンドラインで指定したファイルがシンボリックリンクだったら、sedはリンクを辿り、リンク最終先(大元)のファイルを編集します。デフォルトの動作はシンボリックリンクを解除することで、リンク先は変更されません。

-E
-r
--regexp-extended

基本正規表現ではなく拡張正規表現を使います。拡張正規表現とはegrepが受け付けるものです。バックスラッシュの嵐を減らせるので正規表現がより分かりやすくなります。これは歴史的にはGNU拡張でしたが、 '-E'拡張はPOSIX標準に取り込まれた(http://austingroupbugs.net/view.php?id=528)ので、移植性の為に'-E'を使います。GNU sedは何年も前から文書化されていないオプションとして -E を受け入れていますし、*BSD sedsは何年もの間' -E 'を受け入れていますが、' -E 'を使うスクリプトは他の古いシステムに移植できないかもしれません。「拡張正規表現」参照。

-s
--separate

デフォルトではsedはコマンドラインで指定されたファイル群を1つの長いストリームとして扱います。 このGNU sed拡張はファイルをそれぞれに分けて処理することを可能にします。(‘/abc/,/def/’のような)範囲アドレスが複数のファイルに渡らないようにしたり、行番号をファイルごとにリセットしたり、'$'が各ファイルの最終行にマッチするようにしたり、'R'コマンドで読み込むファイルからの読み込み位置をファイルごとに巻き戻したりします。

--sandbox

サンドボックスモードでは 'e'、'w'、'r'コマンドは弾かれます。それらを含むプログラムは実行されずにアボートします。サンドボックスモードでは、 sed はコマンドラインで指定された入力ファイルに対してのみ機能し、外部プログラムを実行することはできません。

-u
--unbuffered

入出力でのバッファリングをできるかぎり少なくします(これは入力が ' tail -f 'のようなものから来ていて、変換された出力をできるだけ早く見たい場合に特に便利です)。

-z
--null-data
--zero-terminated

入力されるデータの区切りが改行コードではなくASCIIの ‘NUL’ 文字(\x00)文字で終わっているものとして扱います。このオプションは ' sort -z 'や ' find -print0 'のようなコマンドと共に使用して任意のファイル名を処理することができます。

コマンドラインに -e -f --expression --file オプションが指定されていない場合は、コマンドラインの最初のオプションではない引数が、実行されるスクリプトになります。

上記の処理後にコマンドラインパラメータが残っている場合、これらのパラメータは処理対象の入力ファイルの名前として解釈されます。 ファイル名に ‘-’ を指定した場合は標準入力からの入力となります。ファイル名が与えられなかった場合も標準入力として処理されます。


2.3 終了ステータス

0の終了ステータスは成功を表し、0以外の値は失敗を表します。GNU sedは以下の終了ステータス値を返します。

0

完璧に成功。

1

不正なコマンドまたは不正な文法または不正な正規表現または、--posixコマンドラインオプションが指定されているのにGNU sed拡張が使われている。

2

コマンドラインで指定した1つまたはそれ以上ファイルがオープンできなかった(例えばファイルが存在しなかった、また読み取り許可権限が無かった)。但し、オープンできた他のファイルに付いては処理が続行されます。

4

I/Oエラーや実行中の深刻なエラー。GNU sedは即座にアボートします。

加えてsedコマンド'q'や'Q'はsedを指定の終了コード値で終了させることが出来ます(これはGNU sed 拡張です)。

$ echo | sed 'Q42' ; echo $?
42

3 sedスクリプト


3.1 sedスクリプト概要

sedプログラムは1つ以上のsedコマンドで構成され、1つまたはそれ以上(混在もOK)の'-e'、'-f'、'--expression'、'--file'コマンドラインオプションで渡されるか、あるいはこれらのコマンドラインオプションが全く無いときはコマンドラインオプションで無い最初の引数がsedプログラムとして扱われます。この文書で言うsedスクリプトとは通常、スクリプトまたはスクリプトファイルとして渡されたものを順に連結したものを意味しています。「概要」参照。

sedコマンド文法は次の通り。

[addr]X[options]

Xは(英語)1文字のsedコマンドです。[addr]は省略可能な行アドレスです。[addr]が指定されると、sedコマンド X はそのアドレスにマッチした行でのみ実行されます。[addr]は行番号一つ、または正規表現、または行範囲を指定する事ができます(「sedアドレス」参照)。追加の[options]はいくつかのsedコマンドにあります。

次の例は入力の30行目から35行目を削除します。30,35はアドレス範囲です。dは削除コマンドです。

sed '30,35d' input.txt > output.txt

次の例は行頭に‘foo’がある行が見つかるまで全てプリントします。そして行頭に‘foo’がある行を見つかると、sed自身を終了させ、終了ステータス 42を返します。行頭に‘foo’がある行が見つからなかった時(そして他のエラーが発生しなかった時)は、sed終了時に終了ステータス 0 を返します。/^foo/は正規表現アドレスです。qはsed終了コマンドです。42はこのsedコマンドのオプションです。

sed '/^foo/q42' input.txt > output.txt

スクリプト内スクリプトファイル内のコマンド達はセミコロン(;)や改行(ASCII \x0a)で区切る事ができます。'-e'や'-f'コマンドラインオプションで複数のスクリプトを指定することができます。

以下の例は全て等価です。以下の例はふたつのsed操作を実行します。正規表現 /^foo/ にマッチする行を削除します。そして‘hello’が現れると全て‘world’に置換します。

sed '/^foo/d ; s/hello/world/' input.txt > output.txt

sed -e '/^foo/d' -e 's/hello/world/' input.txt > output.txt

echo '/^foo/d' > script.sed
echo 's/hello/world/' >> script.sed
sed -f script.sed input.txt > output.txt

echo 's/hello/world/' > script2.sed
sed -e '/^foo/d' -f script2.sed input.txt > output.txt

sedコマンド'a'、'c'、'i'は文法上、続くコマンドとの区切り文字としてセミコロンを使うことはできません。よって改行で終了せるか、またはスクリプトスクリプトファイルの最後に置く必要があります。コマンドの前には(何もしない)空白文字達を書く事もできます。「複数コマンド文法」参照。


3.2 sedコマンド要約

以下のコマンド群はGNU sedでサポートされています。POSIX標準コマンドもあれば、GNU拡張もあります。各コマンドの詳細と例は次の節をご覧ください。括弧内はコマンドの覚え方(mnemonic)です。(訳注:説明の都合上、コマンドとオプションの間に空白が開いていますが、空白無しで続けても構いません)。

a\
text

(append)行のうしろに text を追加する。

a text

(append)行の後ろに text を追加する(代替文法)。

b label

(branch)指定の label へ無条件ジャンプ。ラベルを省略したときは次のサイクルを開始します。

c\
text

(change)行をtext で置き換える。

c text

(change)行を text で置き換える(代替文法)。

d

(delete)パターンスペースの内容を全削除し、以降のコマンドの実行をスキップして直ちに次のサイクルを開始する。

D

(delete)パターンスペースが改行を含んでいれば、パターンスペースの最初の改行までを削除し、次の入力行を読み込まずに、削除後のままのパターンスペースに対して次のサイクルを開始します。

パターンスペースが改行を含んでいない場合はdコマンドと同じ動作で、次の入力行を読み込み次のサイクルを開始します。

e

(execute)パターンスペース内に見つけたシェルコマンドを実行し、パターンスペースの内容をそのシェルコマンドの出力で置き換えます(末尾の改行は抑制されます)。

e command

(execute)シェルコマンドcommandを実行し、その出力を出力ストリームへ送ります。コマンドは複数行に渡って書くことができ、コマンドの最後以外の各行の末尾にはバックスラッシュ'\'を書きます。

F

(filename)現在の入力ファイル名を(末尾に改行を伴って)出力します(標準入力の場合は'-'を出力))。

g

パターンスペースの内容をホールドスペースの内容で置き換えます(cp hold-space pattern-space)。

G

パターンスペースの内容末尾に改行を追加し、更にホールドスペースの内容を追加します。

h

(hold)ホールドスペースの内容をパターンスペースの内容で置き換えます(cp pattern-space hold-space)。

H

(hold)ホールドスペースの内容末尾に改行を追加し、更にパターンスペースの内容を追加します。

i\
text

(insert)行の前に text を挿入する。

i text

(insert)行の前に text を挿入する(代替文法)。

l

パターンスペースの内容を非表示文字も目に見えるようにプリントする。

n

(next)自動プリントが無効で無い場合はパターンスペースの内容をプリントしてから、パターンスペースの内容を次の入力行で置き換えます。それ以上入力が無い時、sedはそれ以上コマンドを処理することなく終了します。

N

(next)パターンスペースの内容の末尾に改行を追加し、更に次に読み込んだ一行を追加します。それ以上入力が無い時、sedはそれ以上コマンドを処理することなく終了します。

p

(print)パターンスペースの内容をプリントする。

P

(print)パターンスペースの最初の改行(改行含む)までの1行をプリントする。

q[exit-code]

(quit)以降のコマンドや入力処理をせずにsedを終了させる。

Q[exit-code]

(quit)このコマンドはqコマンドと同じですが、パターンスペースの内容をプリントしません。qコマンドと同様にsed呼び出し元へexit codeを返す事ができます。

r filename

(read)filenameというファイル名のファイルを読み込む。

R filename

(read)filenameで指定したファイルからたかだか1行読み込み現在のサイクルの最後または次の入力行が読まれる時に出力ストリームに挿入する。

s/regexp/replacement/[flags]

(substitute) パターンスペース内で正規表現にマッチさせます。マッチしたらマッチした文字列をreplacementで置き換えます。

t label

(test) sコマンドによる置換が成功した後で、かつ最後の入力行が読み込まれてないか他の条件分岐が実行されてない場合、指定のラベルへジャンプします。ラベルを省略したときは次のサイクルを開始します。

T label

(test) sコマンドによる置換が失敗した後で、かつ最後の入力行が読み込まれてないか他の条件分岐が実行されてない場合、指定のラベルへジャンプします。ラベルを省略したときは次のサイクルを開始します。

v [version]

(version)このコマンドはGNU sedでは何もしません(が、コマンドとして有効)。しかしGNU sed 拡張がサポートされていない時や、要求したしたversionが存在しない時は失敗します。

w filename

(write)パターンスペースの内容をfilenameで指定したファイルに書き込む。

W filename

(write)与えられたfilenameのファイル名のファイルに、パターンスペースの先頭から最初の改行まで部分を書き出す。

x

(exchange)パターンスペースの内容とホールドスペースの内容を交換する(swap pattern-space hold-space)。

y/src/dst/

パターンスペース内のsource-charsにある文字を対応するdest-charsの文字で置き換える。

z

(zap)パターンスペースの内容を全削除する。

#

次の改行までをコメントとする。

{ cmd ; cmd ... }

いくつかのコマンドをまとめて1つのグループにする。

=

現在の入力行番号を(末尾に改行付けて)プリントします。

: label

分岐コマンド達('b'、't'、'T')の為の飛び先ラベルを配置します。


3.3 s コマンド

sedでたぶん最も重要なコマンドが s コマンドですが、様々なオプションを持っています。s コマンドの文法は ‘s/regexp/replacement/flags’です。

基本的な概念はシンプルです。s コマンドは与えられた正規表現 regexp でパターンスペースの中から一致する部分を探します。もし一致する部分があればそれを replacement で置き換えます。

正規表現文法について詳しくは「正規表現アドレス」参照。

replacement\n (n は1から9の数字)を含むことができ、それはマッチしたregexp 内の n番目の\(\) に囲まれた部分で置き換えられます。また replacement はエスケープされていない & を含む事ができ、これは正規表現regexp全体とマッチしたものと置き換えられます。

s コマンドの区切りの'/'文字は任意の1文字に置き換える事ができます。(区切りの)'/'文字(または別の文字を使ったのならその文字)がregexpreplacementに現れるのなら、その前に1つの'\'文字を置きます。

最後に、GNU sed拡張として、'\L'、'\l'(訳注:小文字のエル)、'\U'、'\u'、'\E な特殊なつづりを含む事ができます。その意味は以下のとおり。

\L

置換したテキストで、'\U'または'\E'が見つかるまで小文字にする。

\l

(小文字のエル)次の1文字を小文字にする。

\U

置換したテキストで、'\L'または'\E'が出現するまで大文字にする。

\u

次の1文字を大文字にする。

\E

'\L'や'\U'によって始まった文字変換を終了する。

g フラグが指定されていた場合、大文字小文字変換は正規表現の各マッチの範囲内だけで行われ別のマッチまで伝播することはありません。例えば、パターンスペースの内容が‘a-b-’であるとき、次のコマンドを実行すると、

s/\(b\?\)-/x\u\1/g

その出力は‘axxB’となります。最初のマッチは2文字目‘-’で、このとき'\(b\?\)'の中身は空なので、‘\1’は空に置き換えられ、'\u'の次は空になるので何もしません。'b-'を'xB'に置き換える時は、パターンスペースで既に置き換えられた'x'には影響を与えません。

一方、'\l'や'\u'はそれに続く置換が空の場合はその後に続く置換テキストに影響を与えます。パターンスペースに‘a-b-’があるとき、次のコマンド、

s/\(b\?\)-/\u\1x/g

これは‘-’を‘X’にし、‘b-’ を‘Bx’にします。。これが望みの動作で無い場合は、この場合、‘\1’の後ろに‘\E’を置く事で防ぐ事ができます。

'\'文字や'&'文字、改行を含めるには、replacement内においたそれぞれの前に'\'を置いて下さい。

sコマンドはフラグ無しか、1つ以上のフラグを後に続ける事ができます。

g

最初にマッチしたものだけでなくその後もにマッチしたの全てで置換を適用します。

number

number番目のマッチだけ置換します。

sコマンドフラグの相互作用に注意: POSIX規格ではgフラグとnumberフラグを混在させた時に何が起こるかは規定されていません。 sedの各実装の間でわりと普通の動作などというようなものもありません。実装依存です。なおGNU sedでは、この相互作用を定義しています。指定のnumber以前のマッチを無視し、number番目とそれ以降全てのマッチに適用します。

p

置換した場合は、その結果を含むパターンスペースをプリントします。

注意:pフラグとeフラグの両方を使った時は、その指定の順番により全然違う結果をもたらします。 普通は'ep'(evaluate してから print)が望みのものですが、逆順で動いてくれるとデバッグに便利です。このために、sコマンドのフラグは一般には1度しか評価されませんが、デバッグに便利なようにGNU sedの現在の版は'e'の前後に’p'を置くことができます。そうするとeval前のパターンスペースの内容とeval後のパターンスペースの内容をプリントします。この動作は公式文書に掲載されているけれども、将来のバージョンでは変更される可能性があります。(訳注:手元のGNU sed 4.7では動作確認できず)

w filename

置換できたら、指定のファイル名のファイルに結果を書き出します。GNU sed 拡張では、ファイル名として標準エラー出力の'/dev/stderr'と、標準出力の'/dev/stdout'をサポートしています。3

e

このフラグはシェルコマンドからの入力をパターンスペースにパイプラインできます。置換が成功すると、パターンスペースの内容をシェルコマンドとみなして実行し、そのパターンスペースの内容をその出力で置き換えます。末尾の改行は抑制されシェルコマンドには含まれません。また、実行されるコマンドにNUL文字(ASCII \x00)が含まれていた場合の動作は未定義です。これはGNU sed拡張です。

I
i

GNU拡張の'I'フラグはsedregexpの英大文字小文字を区別せずにマッチングするよう指示します。

M
m

GNU sed拡張の'M'フラグは正規表現が複数行マッチモードで動くように指示します。このフラグは'^'と'$'をそれぞれ(通常の振る舞いに加えて)改行の後の空の文字列と改行の前の空の文字列に一致させます。常にバッファの先頭または末尾に一致する特殊文字つづり('\`'と'\'')があります。さらに、複数行モードではピリオド('.')は改行文字とマッチしません。


3.4 よく使われるコマンド群

sedを使った事があれば、あなたはこれらのコマンド全部を知りたいはずです。

#

[アドレス指定不可]

'#'はコメントのはじまりです。次の改行まで続きます。

移植性を気にする場合、(POSIXに準拠していない) sed の実装によっては、スクリプト全体でたった1行のコメントしかサポートされないことがあります。 この場合、スクリプトの最初の文字は''です。

警告:sedスクリプトの最初が'#n'のとき、'-n'(no-autoprint)オプションを指定したのと同じ効果があります(訳注: seq 3 | sed -e '#n' -e '2p' は、seq 3 | sed -n '2p' と等価です)。スクリプトの最初にコメント'#'を書き、それに通常のコメントとしての文字'n'を続ける時は必ず大文字'N'にしてください。または'n'の前に1つ以上の空白を入れて下さい。

q [exit-code]

以降のコマンドや入力を処理せずにsedを終了させる。

例:2行目でプリントを停止する。

$ seq 3 | sed 2q
1
2

このコマンドは単一のアドレスのみ受け入れます(アドレス範囲不可)。注意:'-n'オプションによってサイクル間の自動プリントが抑止されていない場合はパターンスペースの内容をプリントします。sedが返す終了コード値を指定できるのはGNU sed 拡張です。

GNU sed拡張の'Q'コマンドはパターンスペースの内容をプリントせずにsedを終了します。

d

(delete)パターンスペースの内容を全削除し、以降のコマンドの実行をスキップして直ちに次のサイクルを開始する。

例:入力行の2行目を削除。

$ seq 3 | sed 2d
1
3
p

パターンスペースの内容を(標準出力に)プリントする。このコマンドは通常'-n'コマンドラインオプションとの組み合わせでのみ使用されます。

例:入力行の2行目だけをプリントする。

$ seq 3 | sed -n 2p
2
n

自動プリントが無効になって無い時は、パターンスペースの内容をプリントし、プリントの有無にかかわらず入力から読み込んだ次の行でパターンスペースの内容を置き換えます。それ以上入力が無い時、sedはそれ以上コマンドを処理することなく終了します。

このコマンドは行をスキップするのに便利です(例えばN行ごとに処理するなど)。

例:3行おきに置換します(すなわち、2つの'n'コマンドが行を2つスキップする)。

$ seq 6 | sed 'n;n;s/./x/'
1
2
x
4
5
x

GNU sedはこれと同様の結果を得る'first~step'というアドレス文法の拡張を提供しています。

$ seq 6 | sed '0~3s/./x/'
1
2
x
4
5
x
{ commands }

'{'から'}'の間のコマンド達をグループ化します。これは、単一アドレス(またはアドレス範囲)へのマッチによってコマンド群をトリガーしたいときに重宝します。

例:入力行の2行目を置換してプリントします。

$ seq 3 | sed -n '2{s/2/X/ ; p}'
X

3.5 あまり使われないコマンド群

前の節で使用されているものよりも、おそらく使用頻度は低いですが、これらのコマンドを使えば非常に小さくて便利な sed スクリプトを作成することができます。

y/source-chars/dest-chars/

パターンスペース内のsource-charsにある文字を対応するdest-charsの文字で置き換える。

例:a-jの文字をそれぞれ0-9の文字で置き換える。

$ echo hello world | sed 'y/abcdefghij/0123456789/'
74llo worl3

('/'は、任意の y コマンド内で、他の任意の1文字に一律に置き換えることができます)。

'/'(またはその代わりに使用されるその他の文字)、'\'、改行は、'\'でエスケープすることで、source-charsリストやdest-charsリストに記入できます。source-charsdest-charsは正確に同じ文字数でなければなりません。

同じ機能を持つ、GNU coreutils の tr コマンド参照。

a text

行の後ろに text を追加する。これは標準の a コマンドに対するGNU拡張です。詳細は以下を参照。

例:2行目の後ろに‘hello’を追加する。

$ seq 3 | sed '2a hello'
1
2
hello
3

aコマンドは先行する空白('a'と'hello'の間にある空白)を無視します。'a'コマンドの、行末までのテキストを読み取り、行の後ろに追加します。

a\
text

行の後ろに text を追加する。

例:2行目の後ろに‘hello’を追加します(-| で始まる行はsedの出力です)。

$ seq 3 | sed '2a\
hello'
-|1
-|2
-|hello
-|3

a コマンドは、このコマンドに続くテキスト(最後以外は'\'で終わり、出力から削除されます)を現在のサイクルの終わりまたは次の入力行が読み込まれたときに出力されるようにキューに入れます。

GNU拡張では、このコマンドはアドレス範囲を受け付けます。

text のエスケープシーケンスは処理されるので、 text に'\'を文字として入れるには'\\'と記述する必要があります。

最後の行(‘world’)の末尾に'\‘が付いてないことで、そこで a コマンドの終了とみなされ、次の行は次のコマンドの処理を続行します。

$ seq 3 | sed '2a\
hello\
world
3s/./X/'
-|1
-|2
-|hello
-|world
-|X

GNU拡張として、 a コマンドと text を2つの -e パラメータに分割して、スクリプトを簡単にすることができます。

$ seq 3 | sed -e '2a\' -e hello
1
2
hello
3

$ sed -e '2a\' -e "$VAR"
i text

(insert)行の前に text を挿入する。これは、標準の i コマンドに対するGNU拡張です。詳細は以下を参照。

例:2行目の前に‘hello’を挿入する。

$ seq 3 | sed '2i hello'
1
hello
2
3

i コマンドの後の先頭の空白は無視されます。'a'コマンドの、行末までのテキストを読み取り、行の後ろに追加します。

i\
text

このコマンドに続くテキスト行を直ちに出力します。

例: ‘hello’を2行目の前に挿入する(-| はsedの出力)。

$ seq 3 | sed '2i\
hello'
-|1
-|hello
-|2
-|3

GNU拡張では、このコマンドはアドレス範囲を受け付けます。

text のエスケープシーケンスは処理されるので、 text に'\'を文字として入れるには'\\'と記述する必要があります。

最後の行(‘world’)の末尾に'\‘が付いてないことで、そこで a コマンドの終了とみなされ、次の行は次のコマンドの処理を続行します。

$ seq 3 | sed '2i\
hello\
world
s/./X/'
-|X
-|hello
-|world
-|X
-|X

GNU拡張として、 a コマンドと text を2つの -e パラメータに分割して、スクリプトを簡単にすることができます。

$ seq 3 | sed -e '2i\' -e hello
1
hello
2
3

$ sed -e '2i\' -e "$VAR"
c text

対象行を text で置き換えるこれは、標準の c コマンドに対するGNU拡張です。詳細は以下を参照。

例:2行目から9行目までの行の内容を‘hello’で置き換える。

$ seq 10 | sed '2,9c hello'
1
hello
10

cコマンド直後の空白('c'と'hello'の間の空白)は無視されます。'a'コマンドの、行末までのテキストを読み取り、行の後ろに追加します。

c\
text

addressまたはaddress-rangeに一致する行を削除して、このコマンドに続くテキスト行を出力します。

例:2行目から4行目までを‘hello’と‘world’に置換します(-| はsedの出力)。

$ seq 5 | sed '2,4c\
hello\
world'
-|1
-|hello
-|world
-|5

アドレスを指定しない場合、全ての行の内容を置換します。

パターンスペースは削除されているので、このコマンドの実行後に新しいサイクルが開始されます。次の例では、 c は次のサイクルを開始してしまうので、cコマンドで置換されたテキストに対して's/./X/'置換コマンドは実行されません。

$ seq 3 | sed '2c\
hello
s/./X/'
-|X
-|hello
-|X

GNU拡張として、 c コマンドと text を2つの -e パラメータに分割して、スクリプトを簡単にすることができます。

$ seq 3 | sed -e '2c\' -e hello
1
hello
3

$ sed -e '2c\' -e "$VAR"
=

入力行の行番号を(末尾に改行を付けて)プリントします。

$ printf '%s\n' aaa bbb ccc | sed =
1
aaa
2
bbb
3
ccc

GNU拡張では、このコマンドはアドレス範囲を受け付けます。

l line-length

(小文字のエル)パターンスペースを明確な(unambiguous)形式でプリントします。表示不能文字(および'\')はC言語スタイルのエスケープ形式でプリントします。。 長い行は分割され、分割を示す末尾の'\'文字が付きます。 各行の終わりは’$'でマークされています。

line-length は行折り返しの長さを指定します。0が指定された時は行の折り返しをしません。line-lengthを省略すると、コマンドラインで指定したデフォルト値が使われます。line-length パラメータはGNU sed 拡張です。

r filename

(read)filenameというファイル名のファイルを読み込む。例:

$ seq 3 | sed '2r/etc/hostname'
1
2
fencepost.gnu.org
3

filenameの内容をキューに入れ、現在のサイクルの最後または次の入力行が読まれる時に出力ストリームに挿入する。注意:filenameで指定したファイルから読み込みできなかったら、そのファイルは空のファイルであったかのように扱われます。その際何のエラーも出しません。

GNU sed拡張として、 /dev/stdinをファイル名として与えた時は標準入力から読み込みます。

GNU拡張では、このコマンドはアドレス範囲を受け付けます。アドレス指定された各行で、ファイルは再度読み込まれ挿入されます。

w filename

(write)パターンスペースの内容をfilenameで指定したファイルに書き込む。GNU sed 拡張では、ファイル名として標準エラー出力の'/dev/stderr'と、標準出力の'/dev/stdout'をサポートしています。4

最初の入力行が読み取られる前に出力ファイルが作成(または既存ファイルの内容切り捨て(trancate))されます。 同じ filename を参照するすべての w コマンド(成功した s コマンドの w フラグ指定分含む)のファイルへ、ファイルを閉じて再度開くことなく出力します。

D

パターンスペースが改行を含んでいない場合はdコマンドと同じ動作で、次の入力行を読み込み次のサイクルを開始します。逆にパターンスペースが改行を含んでいれば、パターンスペースの最初の改行までを削除し、次の入力行を読み込まずに、削除後のままのパターンスペースに対して次のサイクルを開始します。

N

(next)パターンスペースの内容の末尾に改行を追加し、更に次に読み込んだ一行を追加します。それ以上入力が無い時、sedはそれ以上コマンドを処理することなく終了します。

-z コマンドラインオプションを指定した時は、行と行の間の区切りには、改行(\x0a)の代わりにASCII ‘NUL’(\x00)を追加します。

デフォルトでは sed は次の入力行がなければ終了しません。これはGNUの拡張機能で、 --posix で無効にすることができます。「最終行でのNコマンド」参照。

P

パターンスペースの最初の改行(改行含む)までの1行をプリントする。

h

ホールドスペースの内容をパターンスペースの内容で置き換えます(cp pattern-space hold-space)。

H

(hold)ホールドスペースの内容末尾に改行を追加し、更にパターンスペースの内容を追加します。

g

パターンスペースの内容をホールドスペースの内容で置き換えます(cp hold-space pattern-space)。

G

パターンスペースの内容末尾に改行を追加し、更にホールドスペースの内容を追加します。

x

(exchange)パターンスペースの内容とホールドスペースの内容を交換する(swap pattern-space hold-space)。


3.6 sed導師のためのコマンド群

ほとんどの場合、これらのコマンドを使用するより、おそらく awk またはPerlのようなものでプログラミングする方が得策であることを示しています。しかし時折、 sed にこだわることに専念している人もいますし、これらのコマンドでかなり複雑なスクリプトを書くことができる可能性があります。

: label

[アドレス指定不可]

分岐コマンドの飛び先ラベル label を配置します。他の事は何もしません。

b label

指定の label へ無条件ジャンプします。ラベルを省略したときは次のサイクルを開始します。

t label

sコマンドによる置換が成功した後で、かつ最後の入力行が読み込まれてないか他の条件分岐が実行されてない場合、指定のラベルへジャンプします。ラベルを省略したときは次のサイクルを開始します。


3.7 GNU sed 固有のコマンド

これらのコマンドはGNU sed固有なので、作成するsedプログラムが移植性に留意する必要がない場合のみ使うようにして下さい。以下はGNU sed拡張を確認や日常の作業をするのに役立ちます。でも、まだ標準のsedではサポートされていません。

e [command]

このフラグはシェルコマンドからの入力をパターンスペースにパイプラインできます。eコマンドをパラメータ無しに実行すると、パターンスペース内に見つけたコマンドを実行し、パターンスペースをそのコマンドの実行結果で置き換えます(末尾の改行は抑制されます)。

代わりに、パラメータを指定してeコマンドを実行すると、コマンドはパラメータをシェルコマンドとして解釈して実行し、そのシェルコマンドの実行結果出力ストリームに送ります。コマンドは複数行に渡って書くことができ、コマンドの最後以外の各行の末尾にはバックスラッシュ'\'を書きます。

どちらの場合も、実行されるコマンドに\x00(ASCII NUL)バイトが含まれているとその結果は不明(未定義)です。

rと異なり、シェルコマンドの実行結果を即座にプリントします。 一方、rコマンドはサイクルの終わりまで出力を遅延します。

F

現在の入力ファイル名を(末尾に改行を伴って)出力します(標準入力の場合は'-')。

Q [exit-code]

このコマンドは単一のアドレスのみ受け入れます(アドレス範囲不可)。

このコマンドはqコマンドと同じですが、パターンスペースの内容をプリントしません。qコマンドと同様にsed呼び出し元へexit codeを返す事ができます。

このコマンドの代替方法は-nコマンドラインオプションの使用(スクリプトを必要以上に複雑にする)または次のコード片(スニペット)に頼る(何も表示されないけどファイル末尾まで行を読み込むので時間を無駄にする)ことです。

:eat
$d       最終行で何も出力せず終了
N        何も出力せずもう1行読み込む
g        毎回ホールドスペースの内容(空っぽ)をパターンスペースに上書き
b eat
R filename

(read)filenameで指定したファイルからたかだか1行読み込み現在のサイクルの最後または次の入力行が読まれる時に出力ストリームに挿入する。注意:filenameで指定したファイルから読み込みできなかったり、既にEOFに到達していたら何もしない。なおその時何のエラーも出しません。

rコマンドに/dev/stdinをファイル名として与えた時は標準入力から読み込みます。

T label

sコマンドによる置換が失敗した後で、かつ最後の入力行が読み込まれてないか他の条件分岐が実行されてない場合(暗黙のsコマンド実行結果フラグがまだクリアされてない間)、指定のラベルへジャンプします。ラベルを省略したときは次のサイクルを開始します。

v version

このコマンドはGNU sedでは何もしません(が、コマンドとして有効)。しかしGNU sed 拡張がサポートされていないと失敗します。なぜなら他のsedではこのコマンドは実装されてないからです。加えて、実行に必要なsed のバージョンを 4.0.5 のように指定することができます(訳注:実行するsedが指定バージョンより低い場合はエラー'sed の新版が前提です'になります)。デフォルトのバージョンは 4.0 です。なぜならこのコマンドが最初に実装されたバージョンが4.0だからです。

POSIXLY_CORRECT 環境変数が設定されていても、このコマンドはGNU拡張の利用を許可します。

W filename

パターンスペースの先頭から最初の改行(改行含む)までの内容を、与えられたファイル名のファイルに書き込みます。w コマンドでファイル処理について述べられていることはこのコマンドにも全て当てはまります。

z

このコマンドはパターンスペースの内容を全削除します。これは‘s/.*//’と同様ですが、より有能で、入力ストリームに不正なマルチバイトつづりが現れる時も動作します。POSIXでは‘.’によって不正マルチバイトつづりにマッチしない事を強制します。そのためほとんどのマルチバイトロケール(UTF-8ロケールを含む)ではsedのバッファをスクリプトの途中で全削除する移植性のある方法はありません。


3.8 複数コマンド文法

sedプログラムでは複数のコマンドを与える時にいくつかの書き方があります。

sedスクリプトを( -fオプションを指定して)ファイルとして与える時は改行で区切るのが最も自然な方法です。

コマンドラインでも、全てのsedコマンドは改行で区切る事ができます。代わりに各コマンドをそれぞれ-eオプションの引数として渡す事もできます。

$ seq 6 | sed '1d
3d
5d'
2
4
6

$ seq 6 | sed -e 1d -e 3d -e 5d
2
4
6

一番簡単に複数のコマンドを区切る方法はセミコロン(‘;’)です。

$ seq 6 | sed '1d;3d;5d'
2
4
6

{}btT:コマンドがセミコロンで区切れるのはGNU sed拡張です。

$ seq 4 | sed '{1d;3d}'
2
4

$ seq 6 | sed '{1d;3d};5d'
2
4
6

ラベルを使うコマンドである'b'、't'、'T'、':' は当該のコマンド直後からセミコロンや改行までを読み取ります。先頭の空白文字と末尾の空白文字があっても無視されます。ラベルの例として以下の‘x’をご覧ください。最初の例はGNU sed用です。次の例は移植性のある(GNU sedでなくても動く)同等例です。分岐とラベルについて更に詳しくは「分岐と制御構文」参照。

$ seq 3 | sed '/1/b x ; s/^/=/ ; :x ; 3d'
1
=2

$ seq 3 | sed -e '/1/bx' -e 's/^/=/' -e ':x' -e '3d'
1
=2

3.8.1 sedコマンドに改行が必要な時

次のコマンドはセミコロンで区切ることができなくて改行で区切る事が必要です。

a,c,i (append/change/insert)

aciコマンドの後にはappend/change/insertのためのテキストとして全ての文字を続ける事ができます。そこにセミコロンを使用すると残念な結果になります。

$ seq 2 | sed '1aHello ; 2d'
1
Hello ; 2d
2

これらのコマンドは-eオプションや改行で区切る必要があります。

$ seq 2 | sed -e 1aHello -e 2d
1
Hello

$ seq 2 | sed '1aHello
2d'
1
Hello

aci コマンド直後に直接テキスト(‘Hello’)を追加できる自体がGNU sed拡張であることに注意して下さい。移植性のある、POSIX準拠の代替手段は次のとおりです。

$ seq 2 | sed '1a\
Hello
2d'
1
Hello
# (コメント)

#’から次の改行までの全ての文字はsedから無視されます。

$ seq 3 | sed '# this is a comment ; 2d'
1
2
3


$ seq 3 | sed '# this is a comment
2d'
1
3
r,R,w,W (reading and writing files)

rRwWコマンドはその行末までをファイル名として解釈します。空白やコメントやセミコロンがある場合もファイル名の一部と解釈されるので、その場合は予期しない結果につながります。

$ seq 2 | sed '1w hello.txt ; 2d'
1
2

$ ls -log
total 4
-rw-rw-r-- 1 2 Jan 23 23:03 hello.txt ; 2d

$ cat 'hello.txt ; 2d'
1

rRwWコマンドは(指定したファイルが存在しない等の)ファイル入出力エラーを単純に無視します。ご注意下さい。次の例ではsedはファイル名‘hello.txt’のファイルを読み込もうとしています。. しかしファイルがありませんでした。でもエラーも一切出さずに無視され次のコマンドの実行に移ります。

$ echo x | sed '1rhello.txt ; N'
x
e (シェルコマンド実行)

eコマンドから改行までの全ての文字がシェルに送られます。空白やコメントやセミコロンがある場合もシェルコマンドに含まれるので、その場合は予期しない結果につながります。

$ echo a | sed '1e touch foo#bar'
a

$ ls -1
foo#bar

$ echo a | sed '1e touch foo ; s/a/b/'
sh: 1: s/a/b/: not found
a
s///[we] (上記をewフラグで代用する)

wフラグはs///コマンド実行結果をファイルに書き込み、eフラグはs///コマンド実行結果をシェルコマンドとして実行します。r/R/w/W/eコマンドは改行で終わっていなければなりません。空白やコメントやセミコロンがある場合もファイル名やシェルコマンドの一部と解釈されるので、その場合は予期しない結果につながります。

$ echo a | sed 's/a/b/w1.txt#foo'
b

$ ls -1
1.txt#foo

4 アドレス:行を選択する。


4.1 アドレス概要

アドレスはsedコマンドを実行する対象行を決定します。次のコマンドは、144行でだけ‘hello’を‘world’に置き換えます。

sed '144s/hello/world/' input.txt > output.txt

アドレスが与えられてない時はコマンドは全ての行に対して実行されます。次のコマンドは、入力ファイルから読み込んだ全ての行で‘hello’を‘<s2>world</s2>’に置き換えます。

sed 's/hello/world/' input.txt > output.txt

アドレスは行番号の代わりに正規表現を含む事ができます。次のコマンドは、 ‘apple’を含む行でだけ‘hello’を‘world’に置き換えます。

sed '/apple/s/hello/world/' input.txt > output.txt

アドレス範囲を指定する時は2つのアドレスをカンマ(,)で区切ります。アドレス範囲のアドレスは数字でも正規表現でも両方を混ぜる事もできます。次のコマンドは、4行から17行だけ‘hello’を‘world’に置き換えます(inclusive)。

sed '4,17s/hello/world/' input.txt > output.txt

!文字をアドレス指定の終わり(コマンド文字の前) に指定するとマッチの否定になります。すなわち、!文字がアドレスやアドレス範囲の後ろにあると、選択したアドレス以外の行を対象とします。次のコマンドは‘apple'を含まない行だけ‘hello’を‘world’に置き換えます。

sed '/apple/!s/hello/world/' input.txt > output.txt

次のコマンドは入力ファイルの1から3行と18から最終行だけ‘hello’を‘world’に置き換えます(すなわち excluding lines 4 to 17)。

sed '4,17!s/hello/world/' input.txt > output.txt

4.2 数による行の選択

sedスクリプトのアドレスは以下のいずれかの形式を取ります。

number

行番号を指定すると入力の当該行番号の行だけにマッチします(注意:-i-s コマンドラインオプションを指定しない限り、全ての入力ファイルを通して行番号を振ります)。

$

このアドレス指定は入力ファイル群の最後のファイルの最終行、または、-i or -sコマンドラインオプションが指定された時は入力の各ファイルごとの最終行にマッチします。

first~step

このGNU拡張は、firstと、firstから指定stepごとの行にマッチします。数値 n がいずれかの正の数であるとして、 現在行が式 first + (n * step) に合致する場合に選択されます。したがって、奇数行を選択するには 1〜2 を、偶数行を選択するには 0〜2 を使用します。 2行目から3行おきに選択するには、「 2〜3 」を使用します。 10行目から5行ごとに選択するには、 10〜5 を使用します。 「 50〜0 」は、あいまいな 50 の言い方です。

以下のコマンドはステップアドレスのデモです。

$ seq 10 | sed -n '0~4p'
4
8

$ seq 10 | sed -n '1~3p'
1
4
7
10

4.3 テキストマッチによる対象行選択

GNU sedは以下の正規表現をサポートしています。デフォルトの正規表現はBasic Regular Expression (BRE)(基本正規表現)です。-E-r コマンドラインオプションを指定した場合、正規表現の文法はExtended Regular Expression (ERE)(拡張正規表現)でなければなりません。「BRE vs ERE」参照。

/regexp/

正規表現 regexp にマッチする全ての行を選択します。regexp それ自身が'/'文字を含む時は、'\'でエスケープしなければなりません。

次のコマンドは'/etc/passwd'ファイルの行末が‘bash’である行だけをプリントします。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

GNU拡張の'I'フラグは sed に正規表現 regexpの英大文字小文字を区別せずにマッチングするよう指示します。

他の多くのプログラミング言語では、小文字を区別しない正規表現のマッチングに小文字の i が使用されます。でも sed では、既に i は挿入コマンドを表す文字としてつかわれているのです(「insert command(挿入コマンド)」参照)。

次の2つの例の違いをよく見て下さい。

1つ目の例では、'/b/I'はアドレスです。正規表現は'I'フラグを伴っています。d は削除コマンドです。

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

では、次にの例では'/b/'のみが正規表現です。'i'は挿入コマンドです。'd'は'i'コマンドによって挿入される文字列です。マッチした行の前にテキスト‘d’が挿入されます。

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

GNU sed拡張の'M'フラグは正規表現が複数行マッチモードで動くように指示します。このフラグは'^'と'$'をそれぞれ(通常の振る舞いに加えて)改行の後の空の文字列と改行の前の空の文字列に一致させます。常にバッファの先頭または末尾に一致する特殊文字つづり('\`'と'\'')があります。さらに、複数行モードではピリオド('.')は改行文字とマッチしません。

正規表現アドレスの場合はパターンスペースの現在の内容に作用します。(例えば s/// コマンドで)パターンスペースの内容が変更されると、正規表現マッチングは変更後のテキストに作用します。

次の例ではサイクル間の自動プリントは、-nコマンドラインオプションによって無効にされています。's/2/X/'コマンドは対象行に含まれる‘2’を ‘X’に変更します。'/[0-9]/p'は0から9の数字いずれかを含む行とマッチして、マッチした行をプリントします。次の例では正規表現アドレス/[0-9]/とマッチを試みる前に2行目の内容の数字は'X'に置換されてしまいなくなってしまうので、/[0-9]/とマッチすることもなく、プリントもしません。

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

4.4 範囲アドレス

アドレスの範囲は2つの単一アドレスをカンマ(',')で区切ることで指定することが出来ます。. アドレスの範囲は最初のアドレスにマッチした行から始まって、2つ目のアドレスマッチするまで(2つ目のアドレス含む)続きます((inclusively)。

$ seq 10 | sed -n '4,6p'
4
5
6

2番目のアドレスが正規表現の場合、アドレス範囲の終わる行のマッチングは、最初のアドレスと一致した行の次の行から開始します。なお、範囲は(入力ストリームが最初のアドレスと一致した行で終了する場合を除き)常に2行以上になります。

$ seq 10 | sed -n '4,/[0-9]/p'
4
5

2番目のアドレスが最初のアドレス以下の数値の場合、最初のアドレスのみにマッチします(単一アドレス扱い)。

$ seq 10 | sed -n '4,1p'
4

GNU sed は特殊な2アドレス形式もサポートしています。これらは全てGNU拡張です。

0,/regexp/

行番号0(ゼロ)をアドレスに指定することが出来ます。 '0,/regexp/'のようにすると、sed は入力行の最初からregexpのマッチを試みます。'0,/regexp/'は'1,/regexp/'に似ていますが、'0,/regexp/'のaddr2は入力行の最初から範囲終了としてマッチを試みますが、'1,/regexp/'ではアドレス範囲の原則に従い、範囲は最低2行になります。つまり範囲終了としてマッチを試みるのは2行目からです。

注意:上記が0 アドレスが意味をなす唯一の場所です。0行目というのは存在しませんから、これ以外の方法で 0 アドレスが与えられるとエラーになります。

以下の例はアドレス 0開始と1開始の違いをデモしています。

$ seq 10 | sed -n '1,/[0-9]/p'
1
2

$ seq 10 | sed -n '0,/[0-9]/p'
1
addr1,+N

addr1と、それに続く N 行の範囲にマッチします。

$ seq 10 | sed -n '6,+2p'
6
7
8

addr1 は数値または正規表現を指定できます。

addr1,~N

addr1 とそれに続くNの倍数の行までの範囲にマッチします。次のコマンドは行6から開始して、4の倍数の行8までをプリントします。

$ seq 10 | sed -n '6,~4p'
6
7
8

addr1 は数値または正規表現を指定できます。


5 正規表現: テキストの選択


5.1 sedの正規表現の概要

sed の使い方を知るためには、正規表現を理解する必要があります(正規表現 regular expresson は regexp と略される事があります)。正規表現は対象の文字列に対して左から右へマッチしていくパターンです。ほとんどの文字はそれそのもの(ordinary)です。パターンの中で自分自身を表し、自分自身が表す文字とマッチします。sed の正規表現は2つのスラッシュ('/')で囲んで指定します。

次のコマンドは‘hello’を含む行をプリントします。

sed -n '/hello/p'

上野例は次のgrepコマンドと同じです。

grep 'hello'

正規表現の威力は、パターンに選択肢と繰り返しを含めることができることにあります。これらは特殊文字を使用してパターンにエンコードされています。特殊文字はそれ自体を表す形ではなく、代わりに特殊な方法で解釈されます。

正規表現内で '^' (カレット)は行の先頭にマッチします。'.'(ピリオド)は任意の1文字にマッチします。次の sed コマンドは、行頭が‘b’で、次の1文字が任意の1文字でその次の文字が‘d’である行をプリントします。

$ printf "%s\n" abode bad bed bit bid byte body | sed -n '/^b.d/p'
bad
bed
bid
body

次節では、正規表現における特殊文字の意味と使用法について説明します。


5.2 基本正規表現(basic regular expression;BRE)と拡張正規表現(extended regular expression;ERE)

基本正規表現と拡張正規表現は、指定されたパターンの文法に対する2つのバリエーションです。基本正規表現(BRE)文法は sed (および grep でも同様)のデフォルトです。POSIX指定の -E オプション( -r --regexp-extended )を使用して、拡張正規表現(ERE)文法を有効にします。

GNU sed では、基本正規表現と拡張正規表現の唯一の違いは、いくつかの特殊文字、つまり、 '?'、 '+'、丸括弧('(...)')、中括弧('{...}')、パイプ('|')の動作です。

基本正規表現(BRE)文法では、これらの文字はバックスラッシュ('\')を前に付けない限り特別な意味を持ちません。 逆に拡張正規表現(ERE)文法では、これらの文字はバックスラッシュ('\')が付いていない限り特殊文字です。

望ましいパターンBasic (BRE) SyntaxExtended (ERE) Syntax
文字としての‘+’ (プラス記号)
$ echo 'a+b=c' > foo
$ sed -n '/a+b/p' foo
a+b=c
$ echo 'a+b=c' > foo
$ sed -E -n '/a\+b/p' foo
a+b=c
以下の例では、1つ以上の文字‘a’のあとに1文字の‘b’続きます(プラス記号は特殊メタキャラクタ扱いになっています)。
$ echo aab > foo
$ sed -n '/a\+b/p' foo
aab
$ echo aab > foo
$ sed -E -n '/a+b/p' foo
aab

5.3 基本正規表現文法概要

本節ではsedで使われる正規表現文法をさらっと説明します。

文字

その文字があらわすそのものにマッチします。

*

これはその直前の正規表現の0回以上(0の時は無し)の繰り返しのつづりにマッチします。直前の正規表現は、普通の文字、'\'が前に付いた特殊文字、'.'(ピリオド)、グループ化された正規表現(下記参照)、あるいは角括弧式でなければなりません。GNUの拡張として、接尾辞付きの正規表現の後に * を続けることもできます。 たとえば、 a ** a * と同じです。POSIX 1003.1-2001は * が正規表現または正規表現の部分式の始めに現れるときはそれ自身を意味すると言いますが、多くの非GNU実装はこれをサポートしておらず、移植可能なスクリプトはこれらの文脈では代わりに \* を使うべきです。

.

任意のキャラクタにマッチします。改行も含みます。

^

パターンスペースの最初のNUL文字にマッチします。すなわち、'^'(曲折アクセント記号)に後ろに続くものはパターンスペースの最初の文字になります。

ほとんどのスクリプトでは、パターンスペースは各行の内容に初期化されます(「sedはどのように動くか」参照)。なので、^#include は、行の最初に'#include'がある行のみに一致するものと単純化すると分かりやすいです。例えば、その前にスペースがある場合はマッチは失敗します。この単純化は、元のパターンスペースの内容が変更されていない限り有効です。例えば s コマンドで有効です。

^ は、正規表現または正規表現部分式の先頭(つまり、'\('または'\|'の後)でのみ特殊文字として機能します。ただし、POSIXでは ^ をその文脈では通常の文字として扱う実装が許されているため、移植可能なスクリプトでは、正規表現部分式の冒頭で ^ を使用しないでください。

$

^と同様ですが、これはパターンスペースの終わりを意味します。$ は、正規表現または正規表現部分式の末尾(つまり、'\)'または'\|'の前)でのみ特殊文字として機能します。そして正規表現部分式末尾でのこれの使用は移植性がありません。

[list]
[^list]

listの任意の1文字にマッチします。例えば [aeiou] は(英語の)母音全てにマッチします。listは'char1-char2'のようなつづりを含むことができます。それはchar1 から char2 の任意の1文字にマッチします。「文字クラスと角括弧式」参照。

\+

* と同様ですが、1以上の繰り返しにマッチします。これはGNU拡張です。

\?

* と同様ですが、0または1回の(繰り返し;出現)にマッチします。これはGNU拡張です。

\{i\}

* と同様ですが、正確にi個の繰り返しのつづりにマッチします(i は10進整数値です。移植性を保つには0から255の範囲内で指定して下さい)。

\{i,j\}

繰り返しのうち、i番目からj番目の範囲だけマッチします。, inclusive, sequences.

\{i,\}

i個またはそれ以上の繰り返しのつづりにマッチします。

\(regexp\)

中に書いたregexpを一体としてグループにします。以下のように使います。

regexp1\|regexp2

これはregexp1regexp2 にマッチします。複雑な代替正規表現を使うために括弧を使って下さい。マッチング処理では、左から右へ順番に各選択肢を試し、成功した最初の選択肢が使用されます。これはGNU拡張です。

regexp1regexp2

regexp1regexp2 をつなげた正規表現にマッチします。連結は \| ^ $ よりも強く結合しますが、他の正規表現演算子よりは強く結合しません。

\digit

正規表現内で括弧でくくられた部分のうちdigit番目の部分にマッチします。これは後方参照と呼ばれます。部分式は \( の出現を左から右に順番に数えることによって暗黙にナンバリングされます。

\n

改行にマッチします

\char

charが、 $, *, ., [, \^ のいずれかであるとき、その文字自身にマッチします(特殊文字としての機能を打ち消します)。注意:移植可能と想定できるC言語風のバックスラッシュつづりは'\n'と'\\'だけです。 特に'\t'は移植性がなく、sedのほとんどの実装では、タブ文字ではなく't'にマッチします。

注意:正規表現マッチ機構は貪欲です。すなわち、マッチは左から右へ試みられ、そして同じ文字から始めて2つ以上のマッチが可能であるならば、その最長を選択します。

例:

abcdef

abcdef’にマッチ。

a*b

0個以上の‘a’に続く1文字の‘b’のつづりにマッチします。例えば、‘b’や‘aaaaab’.

a\?b

b’または‘ab’にマッチ。

a\+b\+

1つ以上の‘a’に続く1つ以上の‘b’であるつづりにマッチ。‘ab’は最小のマッチです。他には‘aaaab’や‘abbbbb’や‘aaaaaabbbbbbb’。

.*
.\+

上記2つは両方とも全ての文字にマッチします。けれども1つ目は空文字列含む全ての文字列にマッチする一方、2つ目は1文字以上の文字列にマッチします。

^main.*(.*)

上記は‘main’ではじまり、その後に'('と')'がこの順番で出現する文字列にマッチします。‘n’と‘(’と‘)’は隣接している必要はありません。

^#

#’で始まるストリングにマッチします。

\\$

1つのバックスラッシュ'\'で終わる文字列にマッチします。この正規表現には特殊文字のバックスラッシュとその意味を打ち消すエスケープ用のバックスラッシュの、2つのバックスラッシュが含まれています。

\$

一方、上記は1つの'$'にマッチします。なぜなら$特殊文字の意味がバックスラッシュによってエスケープされているからです。

[a-zA-Z0-9]

Cロケールでは、これはASCII文字と数字にマッチします。

[^ «TAB»]\+

(ここで «TAB» はタブ文字(ASCII HT;\x09)を表します)上記はスペース(0x20)またはタブ(0x09)以外の任意の文字の1文字以上にマッチします。通常これは(英語の)単語を意味します。

^\(.*\)\n\1$

これは、改行で区切られた2つの等しい部分文字列で構成される文字列と一致します。

.\{9\}A$

これは9文字にマッチし、その後に行末に'A'が続きます。

^.\{15\}A

これは16文字でかつその最後が‘A’である文字列にマッチします。


5.4 拡張正規表現文法概要

基本正規表現と拡張正規表現の唯一の違いは、いくつかの特殊文字、つまり、 '?'、 '+'、丸括弧('(...)')、中括弧('{...}')、パイプ('|')の動作です。基本正規表現では、特殊文字として振る舞わせるにはこれらをエスケープする必要がありますが、逆に拡張正規表現を使用するときにはリテラル文字と一致させるにはエスケープする必要があります。ここで‘|’(パイプ)は特別な意味を持ちます。‘\|’はGNUの拡張機能なので、標準の基本正規表現では機能が提供されません。

例:

abc?

上記は拡張正規表現を使用すると、'abc\?'になります。'abc\?'は、拡張正規表現ではリテラル文字列‘abc?’にマッチします。

c\+

拡張正規表現では‘c+’になります。上記は拡張正規表現では1つ以上の‘c’にマッチします。

a\{3,\}

拡張正規表現では‘a{3,}’となります。上記は拡張正規表現では3個以上の‘a’にマッチします。

\(abc\)\{2,3\}

拡張正規表現では‘(abc){2,3}’になります。‘abcabc’か‘abcabcabc’のどちらかにマッチします。

\(abc*\)\1

拡張正規表現では‘(abc*)\1’となります。後方参照は拡張正規表現でも依然としてエスケープされる必要があります。

a\|b

拡張正規表現では‘a|b’となります。‘a’または‘b’にマッチします。


5.5 文字クラスと角括弧式

角括弧式は ‘[’と‘]’で囲まれた文字のリストです。リスト内の任意の1文字にマッチします。最初の文字が‘^’の時はリストに無い任意の1文字にマッチします。次のコマンドは‘gray’または‘grey’を‘blue’に置き換えます。

sed  's/gr[ae]y/blue/'

角括弧式は、基本拡張の両方の正規表現で使用できます(つまり、 -E -r の有無にかかわらず)。

角括弧式の中では、範囲式はハイフン'-'で区切られた2文字で構成されています。それは2つの文字の間でソートする任意の1文字と一致します。包括的(inclusive)です。デフォルトのCロケールでは、ソート順はネイティブの文字順です。 たとえば、'[a-d]'は'[abcd]'と同じです。

最後に、以下のように、特定の名前付き文字クラスが角括弧式の中で使えるよう事前定義されています。

これらの名前付きクラスはブラケット([...])の中でしか使えません。正しい使い方:

$ echo 1 | sed 's/[[:digit:]]/X/'
X

間違った使い方はsedの新しい版では拒絶されます。より古いバージョンはそれを受け入れましたが、現在それは単なる角括弧式として扱われます('[dgit:]'と等価です。すなわち、文字'd'、'g'、'i'、't'、':'のいずれかにマッチします)。

# GNU sed の現在の版ではこれは不正として拒絶される
$ echo 1 | sed 's/[:digit:]/X/'
sed: character class syntax is [[:space:]], not [:space:]

# GNU sed の古い版
$ echo 1 | sed 's/[:digit:]/X/'
1
[:alnum:]

英数字を表すのは‘[:alpha:]’と‘[:digit:]’です。これは‘C’ロケールとACII文字エンコーディングでは‘[0-9A-Za-z]’と同じです。

[:alpha:]

アルファベット文字は‘[:lower:]’と‘[:upper:]’です。‘C’ロケールとASCII文字エンコーディングでは‘[A-Za-z]’と同じです。

[:blank:]

空白文字は空白(0x20)とタブ(0x09)です。

[:cntrl:]

コントロール文字。ASCIIでは8進数の000から037と、177(DEL)です(16進数では \x00から\x1Fと\x7F)。他の文字セットは、もしそれがあればその文字と等価です。

[:digit:]

Digits(数字): 0 1 2 3 4 5 6 7 8 9.

[:graph:]

Graphical characters(グラフィック文字): ‘[:alnum:]’と‘[:punct:]’です。

[:lower:]

小文字。‘C’ロケールでASCIIエンコーディングでは a b c d e f g h i j k l m n o p q r s t u v w x y z です。

[:print:]

Printable characters(表示可能文字)。‘[:alnum:]’と‘[:punct:]’と空白です

[:punct:]

Punctuation characters(句読点文字)。‘C’ロケールでASCIIエンコーディングではこれは以下のものです。! ” # $ % & ' ( ) * + , - . / : ; < = > ?@ [ \ ] ^ _ ` { | } ~

[:space:]

Space characters(空白文字)。‘C’ロケールでASCIIエンコーディングではこれは、タブ(HT;0x09)、改行(LF;0x0A)、垂直タブ(VT;0x0B)、フォームフィード(FF;0x0C)、キャリッジリターン(CR;0x0D)、空白(0x20)です。

[:upper:]

大文字。‘C’ロケールでASCIIエンコーディングではこれは、A B C D E F G H I J K L M N O P Q R S T U V W X Y Z です。.

[:xdigit:]

16進数。0 1 2 3 4 5 6 7 8 9 A B C D E F a b c d e f です。

注意: これらのクラス名のブラケット('[',']')は記号名の一部であり、角括弧式を区切る大括弧('[',']')に加えて含める必要があります。

ほとんどのメタキャラクタは角括弧式の中ではその特別な意味を失います。

]

最初のリスト項目ではない場合は、角括弧式を終了します。したがって、文字として'] 'の文字をリスト項目にする場合は、最初にそれを配置する必要があります。

-

リストの最初または最後ではない場合、または範囲の終点でない場合は、範囲を表します。

^

リストにない文字を表します。リストの項目として文字としての‘^’を使いたい場合はリストの最初以外に配置します。

TODO: incorporate this paragraph (copied verbatim from BRE section).

リストの中では $, *, ., [, \ は特殊文字ではなく通常の文字です。例えば、[\*] は文字‘\’か文字‘*’のどちらかにマッチします。なぜなら\ は特殊文字ではないからです。けれども、[.ch.][=a=][:space:]のような文字列はリスト内では特殊です。これらはそれぞれ照合シンボル、等価クラス、文字クラスを表します。したがって、[の後に.=:が続く場合、 list 内で特別です。また、POSIXLY_CORRECTモードではない場合、\n \tのような特別なエスケープはリスト内でで無効になりません。「エスケープ」参照。

[.

照合シンボルの開始を表します。

.]

照合シンボルの終了を表します。

[=

等価クラスの開始を表します。

=]

等価クラスの終了を表します。

[:

文字クラスシンボルの開始を表し、その後に有効な文字クラス名を続ける必要があります。

:]

文字クラスシンボルの終了を表します。


5.6 正規表現拡張

以下のつづり達は(アドレスs コマンドで使われる)正規表現の内側で特別な意味を持ちます。

これらは基本拡張の両方の正規表現で使用できます(つまり、 -E -r の有無にかかわらず)。

\w

任意の「単語」の文字にマッチします。「単語」の文字とは、任意の文字または数字またはアンダースコア'_'です。

$ echo "abc %-= def." | sed 's/\w/X/g'
XXX %-= XXX.
\W

「非単語」文字にマッチします。

$ echo "abc %-= def." | sed 's/\W/X/g'
abcXXXXXdefX
\b

単語の境界に一致します。 つまり、左側の文字が「単語」の文字で右側の文字が「非単語」の文字である場合、またはその逆の場合に一致します。

$ echo "abc %-= def." | sed 's/\b/X/g'
XabcX %-= XdefX.
\B

単語の境界を除くあらゆる場所に一致します。 つまり、左側の文字と右側の文字が両方とも「単語」の文字であるか、両方の「非単語」の文字であるかに一致します。

$ echo "abc %-= def." | sed 's/\B/X/g'
aXbXc X%X-X=X dXeXf.X
\s

空白文字(空白とタブ)にマッチします。パターンスペースやホールドスペースに埋め込まれた改行にも一致します。

$ echo "abc %-= def." | sed 's/\s/X/g'
abcX%-=Xdef.
\S

非空白文字にマッチします。

$ echo "abc %-= def." | sed 's/\S/X/g'
XXX XXX XXXX
\<

単語の最初にマッチします。

$ echo "abc %-= def." | sed 's/\</X/g'
Xabc %-= Xdef.
\>

単語の最後にマッチします。

$ echo "abc %-= def." | sed 's/\>/X/g'
abcX %-= defX.
\`

パターンスペースの最初にのみマッチします。これは複数行モードの ^ とは異なります。

以下の2つの例を比べてみて下さい。

$ printf "a\nb\nc\n" | sed 'N;N;s/^/X/gm'
Xa
Xb
Xc

$ printf "a\nb\nc\n" | sed 'N;N;s/\`/X/gm'
Xa
b
c
\'

パターンスペースの最後にのみマッチします。これは複数行モードでの $ とは異なります。


5.7 後方参照と部分式

後方参照は、一致した正規表現の前の部分を参照する正規表現コマンドです。後方参照はバックスラッシュと1桁の数字で指定されます(例:\1 )。それらが参照する正規表現の一部は部分式と呼ばれ、丸括弧で示されます。

後方参照と部分式は、正規表現検索パターンの中とsコマンドreplacementの部分の2つの場合に使用されます(「正規表現アドレス」と「The "s" Command」参照)。

正規表現パターンでは、後方参照は、以前に一致した部分式と同じ内容を一致させるために使用されます。次の例では、部分式は‘.’で、この場合任意の1文字を意味します(丸括弧で囲まれていると部分式になります)。後方参照 '\1'は、部分式と同じ内容(同じ文字)に一致するように要求します。

以下のコマンドは、任意の文字で始まり、その後に文字‘o’、その後に最初の文字と同じ文字が続く単語に一致します。

$ sed -E -n '/^(.)o\1$/p' /usr/share/dict/words
bob
mom
non
pop
sos
tot
wow

複数の部分式は左から右に自動的に採番されます。このコマンドは6文字の回文を検索します(最初の3文字は3つの部分式で、その後に3つの後方参照が逆順に続きます)。

$ sed -E -n '/^(.)(.)(.)\3\2\1$/p' /usr/share/dict/words
redder

s コマンドでは、 replacement 部分で後方参照を使用して regexp 部分の部分式を参照できます。

次の例では、スペースで区切られた2つの単語に一致させるために、正規表現で2つの部分式を使用しています。 replacement 部分の後方参照は、単語を異なる順序で表示します。

$ echo "James Bond" | sed -E 's/(.*) (.*)/The name is \2, \1 \2./'
The name is Bond, James Bond.

alternation('|')が使用されている時、部分マッチした側にグループが含まれていないと、後方参照は全体のマッチを失敗させます。例えば‘a(.)|b\1’は‘ba’にはマッチしません。-e やファイル(‘-f file’)で複数の正規表現を指定する時、後方参照は指定ごとの各正規表現ローカルです。


5.8 エスケープシーケンス - 特殊文字の指定

この章までは、 sed に曲折アクセント記号('^')を特殊文字として解釈するのではなく、文字通りに解釈するように指示する '\^'という形式のエスケープにしか遭遇しませんでした。例えば、‘\*’は0個以上のバックスラッシュ'\'ではなく1文字の'*'にマッチします。

この章では、別の種類のエスケープ6、つまり通常文字そのものとして使用される文字・文字のつづりに適用されるエスケープ、およびsedが特殊文字に置き換えるエスケープを紹介します。これは、印刷不可能な文字をパターンで視覚的にエンコードする方法を提供します。 sed スクリプト内の非印刷文字の表示に制限はありませんが、スクリプトがシェル内またはテキスト編集によって準備されている場合は、通常、それを示す文字コードを指定するよりも以下のエスケープシーケンスのいずれかを使用するほうが簡単です。

それらのエスケープの一覧です。

\a

BEL文字を生成するかマッチします。それは"alert"(ASCII BEL;0x07)です。

\f

フォームフィード(ASCII FF;0x0C)を生成するかマッチします。

\n

改行(ASCII LF;0x0A)を生成するかマッチします。

\r

キャリッジ・リターン(ASCII CR;0x0D)を生成するかマッチします。

\t

タブ(水平タブ)(ASCII HT;0x09)を生成するかマッチします。

\v

垂直タブ(ASCII VT;0x0B)を生成するかマッチします。

\cx

コントロール文字(CONTROL-x)を生成するかマッチします。ここで x は任意の文字です。‘\cx’の正確な効果は以下のとおりです。なお、x が小文字の場合は大文字に変換したうえで評価されます。それから文字の6ビット目(16進数で 0x40)を反転させます。したがって、「\cz」は16進数1Aになり、「\c{」は16進数3Bになり、「\c;」は16進数7Bになります。

\dxxx

ASCII 値が10進数の xxx の文字を生成またはマッチします。

\oxxx

ASCII 値が8進数の xxx の文字を生成またはマッチします。

\xyy

ASCII 値が16進数の yy の文字を生成またはマッチします。

\b’(バックスペース)は、既存の「単語境界」の意味と競合するため省かれています。

5.8.1 エスケープ文字の打ち消し

GNU seds///コマンドの正規表現マッチングやアドレスのマッチングにテキストを渡す前にエスケープシーケンスを処理します。次の2つのコマンドは等価です(‘0x5e’は16進表記した文字‘^’のASCII値)。

$ echo 'a^c' | sed 's/^/b/'
ba^c

$ echo 'a^c' | sed 's/\x5e/b/'
ba^c

[’のASCII値が‘0x5b'、‘]’のASCII値が‘0x5d’であるのだからと、次の通り書いたとします。

$ echo abc | sed 's/[a]/x/'
Xbc
$ echo abc | sed 's/\x5ba\x5d/x/'
Xbc

ただし、予期しない境界ギリギリの状態(edge-case)が発生するため、このような特殊文字は避けてください。例えば次の2つの例は等価ではありません。

$ echo 'a^c' | sed 's/\^/b/'
abc

$ echo 'a^c' | sed 's/\\\x5e/b/'
a^c

5.9 マルチバイト文字とロケールに関する考慮事項

GNU sedはマルチバイトロケール(例 UTF-8)でマルチバイト文字を適切に処理できます。7

次の例ではギリシャ文字の大文字のシグマ (Σ, ユニコードでは 0x03A3)を使用しています。UTF-8ロケールではsedは2オクテット(2バイト)であってもシグマを正しく1文字として処理します。

$ locale | grep LANG
LANG=en_US.UTF-8

$ printf 'a\u03A3b'
aΣb

$ printf 'a\u03A3b' | sed 's/./X/g'
XXX

$ printf 'a\u03A3b' | od -tx1 -An
 61 ce a3 62

1オクテット(1バイト)単位の処理をsedに強制したいときは、(POSIXロケールとして知られている)Cロケールを使って下さい。

$ printf 'a\u03A3b' | LC_ALL=C sed 's/./X/g'
XXXX

5.9.1 不正なマルチバイト文字

マルチバイトロケールでのsedの正規表現は不正なマルチバイトつづりにマッチできません。

次の例は不完全なマルチバイト文字である0xCEです(�と表示されます)。正規表現‘.’はこれにマッチできません。

$ printf 'a\xCEb\n'
a�e

$ printf 'a\xCEb\n' | sed 's/./X/g'
X�X

$ printf 'a\xCEc\n' | sed 's/./X/g' | od -tx1c -An
  58  ce  58  0a
   X      X   \n

同様に、’全てをキャッチする’ 正規表現 ‘.*’ を使ってみても行全体ともマッチできません。

$ printf 'a\xCEc\n' | sed 's/.*//' | od -tx1c -An
  ce  63  0a
       c  \n

GNU sedには不正なマルチバイト文字に関係なくパターンスペースの内容を全削除する特別なコマンドzコマンドがあります(s/.*//のように動作しますが、無効なマルチバイト文字も削除します。

$ printf 'a\xCEc\n' | sed 'z' | od -tx1c -An
   0a
   \n

あるいは、Cロケールにして1オクテット単位(1バイト単位で)処理させます(Cロケールでは全てのオクテット値(バイト値)が有効です)。

$ printf 'a\xCEc\n' | LC_ALL=C sed 's/.*//' | od -tx1c -An
  0a
  \n

sedが不正なマルチバイト文字を処理できないことを、ファイル内のそのような不正つづりの検知に使うことができます。以下の例では\xCE\xCEは不正マルチバイトつづりですが、 \xCE\A3は適正なマルチバイト文字(ギリシャ文字のシグマ)を含むつづりです。

sedプログラムはs/.//gによって全ての適正な文字を取り除きます。パターンスペースに残った任意の内容(不正なマルチバイト文字)は、Hコマンドによってホールドスペースに追加されます。最終行($)でホールドスペースの内容は回収されます(x)。改行が全て削除され(s/\n//g)、残った任意のデータが非表示文字も印刷可能な形で(unambiguously)プリントされます(l)。したがって、不正なマルチバイトつづりは8進値として出力されます。

$ printf 'ab\nc\n\xCE\xCEde\n\xCE\xA3f\n' > invalid.txt

$ cat invalid.txt
ab
c
��de
Σf

$ sed -n 's/.//g ; H ; ${x;s/\n//g;l}' invalid.txt
\316\316$

さらにいくつかのコマンドを使用すると、 sed は無効な各文字に対応する正確な行(この例では3行目)の行番号を表示できます。これらの文字は、 C ロケールを強制し、8進エスケープシーケンスを使用することで削除できます。

$ sed -n 's/.//g;=;l' invalid.txt | paste - -  | awk '$2!="$"'
3       \316\316$

$ LC_ALL=C sed '3s/\o316\o316//' invalid.txt > fixed.txt

5.9.2 (英語の)大文字小文字変換

GNU sed’の置換コマンド(s)は\U\Lを使うことで大文字小文字変換をサポートします。 これらの変換はマルチバイト文字をサポートします。

$ printf 'ABC\u03a3\n'
ABCΣ

$ printf 'ABC\u03a3\n' | sed 's/.*/\L&/'
abcσ

The "s" Command」参照

5.9.3 マルチバイト正規表現文字クラス

Cロケール以外の他のロケールでは、ソート順は指定されておらず、 ‘[a-d]’は‘[abcd]’または ‘[aBbCcDd]’と同等であるか、または任意の文字、またはそれが一致する文字のセットと一致しない可能性があります。マッチは不規則かもしれません。角括弧式の伝統的な解釈を取得するために、環境変数 LC_ALL を値 C に設定して ' C 'ロケールを使用できます。

# TODO: is there any real-world system/locale where 'A'
#       is replaced by '-' ?
$ echo A | sed 's/[a-z]/-/'
A

これらの解釈は LC_CTYPE ロケールに依存します。 たとえば、 [[:alnum:]] は、現在のロケールでの数字と文字の文字クラスを意味します。

TODO: show example of collation

# TODO: this works on glibc systems, not on musl-libc/freebsd/macosx.
$ printf 'cliché\n' | LC_ALL=fr_FR.utf8 sed 's/[[=e=]]/X/g'
clichX

6 sedの高度な話題: サイクルとバッファ


6.1 sedはどのように動いているか

sedは2つのバッファを保持しています。それは現に活動中のパターンスペースと補助のホールドスペースです。両方とも最初は空です。

sedは入力の各行ごとに以下のサイクルを実行します。最初にsedは入力ストリームから1行読み取り、末尾の改行を削除し、パターンスペースに入れます。次にコマンド群を実行します。各コマンドはそのコマンドに関連付けられたアドレスを持つこともできます。アドレスは一種の条件コードで、条件に合致した時だけそのコマンドが実行されます。

スクリプトの最後まで到達した時(-nが指定されてなければ)、最初に一行読み込む時に削除した行末の改行を戻してから(読み込む時に行末の改行を削除してなかったらそのまま)、パターンスペースの内容を出力ストリームにプリントアウトします。8 それから次の入力行の為のサイクルを開始します。

Dコマンドのような)特殊コマンドが使われてない限り、次のサイクルを開始する前にパターンスペースの内容を削除します。一方ホールドスペースの内容はサイクル毎に削除しません。以降の新しいサイクルが始まっても内容を保持しています(両バッファの間でデータを移動させるためのコマンド、 ‘h’, ‘H’, ‘x’, ‘g’, ‘G’ 参照)。


6.2 ホールド用とパターン用のバッファ

TODO


6.3 複数行テクニック - D,G,H,N,P コマンドで複数行処理

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

これらのコマンドの動作は以下の通り。

D

パターンスペースから最初の改行まで(改行含む)1行を削除する。パターンスペースのプリントや全削除をスキップして次のサイクルを開始する。

G

パターンスペースの末尾に改行を追加し更にホールドスペースから1行パターンスペースに追加します。

H

ホールドスペースの末尾に改行を追加し更にパターンスペースから1行追加します。

N

1行追加。入力ストリームから1行パターンスペースに追加する。

P

パターンスペースの最初の改行(改行含む)までの1行をプリントする。

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

$ seq 6 | sed -n 'N;l;D'
1\n2$
2\n3$
3\n4$
4\n5$
5\n6$
  1. sedは最初の1行をパターンスペースに読み込み(すなわちパターンスペースの内容は‘1’)
  2. 毎度のサイクルを始めます。Nコマンドは(最初の1行をパターンスペースに読み込む時に取り除いた)改行を追加し、更に次の1行をパターンスペースに読み込みます( すなわちパターンスペースの内容は‘1’, ‘\n’, ‘2’ となる)。
  3. l(小文字のエル)コマンドはパターンスペースの内容を非表示文字等含めて目に見える形でプリントします(削除はしない)。
  4. Dコマンドはパターンスペースの内容を最初の改行まで(その改行含む)削除し、そしてDパターンスペースの削除をスキップして次のサイクルを開始します (よって、次のサイクルは(2行目の)2’だけ状態から始まる)。
  5. そのサイクルでNコマンドは同様に削除してあった改行追加し入力行をパターンスペースに追加します(すなわち、‘2’, ‘\n’, ‘3’).

(行ごとではなく)段落などのテキストブロックを処理するには以下のような構文を使用するのが一般的です。

sed '/./{H;$!d} ; x ; s/REGEXP/REPLACEMENT/'
  1. スクリプト1行目の/./{H;$!d}は空行以外の全ての行に対して実行され、(パターンスペース内の) 現在行をホールドスペースに追加します。$!によって最終行以外ではパターンスペースの内容の全削除と残りの処理をスキップして次のサイクルを開始します。
  2. 残りのスクリプトxs は空行(すなわち段落の区切り)に対してだけ実行されます。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

注釈付きの例については、「複数行にわたるテキスト検索」や「行の長さを揃える」参照。


6.4 分岐と制御構文

分岐コマンドのbtTsedプログラムの流れを変える事を可能にします。

デフォルトではsedは入力行をパターンスペースに読み込み、それから全てのコマンドを順番に実行します。アドレス指定の無いコマンドは全ての行で実行されます。アドレス指定のあるコマンドはアドレス指定に合致する行に対してだけ実行されます。「実行サイクル」と「アドレス概要」参照。

sedには典型的なif/then構文がありません。代わりにいくつかのコマンドは、条件文や、制御の流れを変えるために使えます。

d

パターンスペースの内容を全削除し、このコマンド以降のスクリプトの実行をスキップしてパターンスペースの内容をプリントせずに次のサイクルを開始する。

D

パターンスペースの最初の改行まで(その改行含む)削除し、このコマンド以降のスクリプトの実行をスキップしてパターンスペースの内容をプリントせずに次のサイクルを開始する。

[addr]X
[addr]{ X ; X ; X }
/regexp/X
/regexp/{ X ; X ; X }

アドレスや正規表現はif/then構文として使える。「if パターンスペースの内容が[addr] にマッチ then コマンド実行」。例:/^#/d は、「if パターンスペースが正規表現^#(行頭が#)にマッチする then d コマンド実行(当該行を削除し、プリントせず、次のサイクルを開始する)」。

b

無条件分岐(指定のラベルへジャンプ。当該スクリプトの中で前にジャンプしてループを構成するのに使ったり、条件と組み合わせてelse部分をスキップするのに使える。あくまで当該スクリプトの中でジャンプするだけで当該サイクルを終了したり次のサイクルを開始することはない)。分岐はアドレスと組み合わせると、条件に適合した時だけジャンプさせることができます。

t

条件分岐。最後に読み込まれた入力行のs///コマンドが成功し、かつ、まだ他の条件分岐が実行されてない場合に分岐実行する(指定のラベルへジャンプ)。

T

tコマンドと逆に、最後に読み込まれた入力行の's'コマンドが失敗した場合に分岐する。

以下の2つのsedプログラムは等価です。最初の(わざとらしい)例は‘1’を含む行の時にs///をスキップするためにbコマンドを使っています。2番目の例ではアドレスの否定( '')を使用して、目的の行のみs///コマンドを実行します。いずれにせよy///コマンドは全ての行で実行されます。

$ printf '%s\n' a1 a2 a3 | sed -E '/1/bx ; s/a/z/ ; :x ; y/123/456/'
a4
z5
z6

$ printf '%s\n' a1 a2 a3 | sed -E '/1/!s/a/z/ ; y/123/456/'
a4
z5
z6

6.4.1 分岐とサイクル

bコマンドやtコマンドやTコマンドは、コマンドに続くジャンプ先ラベルが必要です(通常はアルファベット1文字)。飛び先ラベルはコロン(:)に続く1文字またはそれ以上の文字列として定義します(例えば‘:x’)。なお、ブランチコマンドでラベルを省略すると次のサイクルを開始します。ブランチコマンドによるジャンプと次のサイクルの開始との違いに注意して下さい。次のサイクルの開始時はsedはまずパターンスペースの内容をプリントして次に入力ストリームから1行パターンスペースに読み込みます。一方ラベルへのジャンプは(それがたとえプログラムの先頭へジャンプしたとしても)、パターンスペースの内容はプリントされませんし入力ストリームから次の1行を読み込む事もありません。

以下のプログラム自身は何もしません。(このプログラム唯一のコマンドである)bコマンドは飛び先ラベルが書かれていないので次のサイクルを開始します。よってどのサイクルでもパターンスペースの内容がプリントされて入力ストリームから次の入力行を読み取ります。

$ seq 3 | sed b
1
2
3

次のサンプルは無限ループに陥ります。一切プリントすることなく終了もしません(訳注:CTRL+C等で強制停止させる)。bコマンドは‘x’ラベルにジャンプし、そして永遠に最初のサイクルにとどまり決して新しいサイクルが始まることはありません。

$ seq 3 | sed ':x ; bx'

# 上記コマンド実行には gnu sed が必要です。
# (ラベル定義のあとで改行しないでいいのは gnu 拡張です。)gnu sed 以外でも動くようにするには以下のようにします。
#     sed -e ':x' -e bx

分岐はしばしばnコマンドやNコマンドと一緒に使われます。両コマンドは次のサイクルを開始することなしに入力ストリームから1行入力行をパターンスペースに入れます。 nコマンドはパターンスペースの内容をプリントして、そしてパターンスペースの内容を全削除してから入力ストリームから次の1行を読み込みます。一方、 Nコマンドはひたすら改行と次の入力行をパターンスペースに追加していきます。

ここで以下の2つの例について考えてみます。

$ seq 3 | sed ':x ; n ; bx'
1
2
3

$ seq 3 | sed ':x ; N ; bx'
1
2
3

6.4.2 分岐例: 行連結

現実的な分岐の使用例として、通常電子メールメッセージのエンコードに使用される quoted-printable ファイルの場合を考えます。これらのファイルでは、長い行が分割され、行末に単一の「=」文字からなるソフト改行が付けられます。

$ cat jaques.txt
All the wor=
ld's a stag=
e,
And all the=
 men and wo=
men merely =
players:
They have t=
heir exits =
and their e=
ntrances;
And one man=
 in his tim=
e plays man=
y parts.

次のプログラムは、アドレス一致 '/=$/'を条件として使用します。現在のパターンスペースが '='で終わっている場合は、 N を使って次の入力行を読み込み、改行が後ろに続くすべての '='文字を置き換え、新しいサイクルを開始せずに無条件でプログラムの先頭に分岐します(b)。パターンスペースが「=」で終わっていない場合は、デフォルトのアクションが実行されます。パターンスペースがプリントされ、次のサイクルが開始されます。

$ sed ':x ; /=$/ { N ; s/=\n//g ; bx }' jaques.txt
All the world's a stage,
And all the men and women merely players:
They have their exits and their entrances;
And one man in his time plays many parts.

お次は、少し異なるアプローチをしたプログラムです。最後の行を除くすべての行で、Nは行をパターンスペースに追加します。それから置換コマンドは、'= 'と、それに続く改行なつづりを空文字列に置き換える事によってソフト改行を取り除きます。もし置換が成功した場合(つまり、パターンスペースに結合すべき行が含まれていた場合)、条件付き分岐コマンド t は、現在のサイクルを完了させることもなく、新しいサイクルを開始することもなくプログラムの先頭にジャンプします。置換が失敗した場合(ソフト改行がないことを意味する)、 t コマンドは分岐しません。そして、 P は最初の改行までパターンスペースの内容を印刷し、 D は最初の新しい行までパターンスペースの内容を削除します。( N P D コマンドの詳細については、「複数行テクニック」参照)。

$ sed ':x ; $!N ; s/=\n// ; tx ; P ; D' jaques.txt
All the world's a stage,
And all the men and women merely players:
They have their exits and their entrances;
And one man in his time plays many parts.

更に行連結の例を見たい方は「行連結」参照。


7 スクリプト例をいくつか

ここには、sedをマスターするのに参考になる、いくつかのスクリプトがあります。


7.1行連結

この節では、 N D P コマンドを使用して複数行を処理し、btコマンドを使用して分岐します。「複数行テクニック」、「分岐とフロー制御」参照。

指定行を連結する(例:2行目と3行目を結合する必要がある場合)。

$ cat lines.txt
hello
hel
lo
hello

$ sed '2{N;s/\n//;}' lines.txt
hello
hello
hello

バックスラッシュで継続された行を連結する。

$ cat 1.txt
this \
is \
a \
long \
line
and another \
line

$ sed -e ':x /\\$/ { N; s/\\\n//g ; bx }'  1.txt
this is a long line
and another line


#TODO: The above requires gnu sed.
#      non-gnu seds need newlines after ':' and 'b'

空白で始まる行(例:SMTPヘッダ)を結合します。

$ cat 2.txt
Subject: Hello
    World
Content-Type: multipart/alternative;
    boundary=94eb2c190cc6370f06054535da6a
Date: Tue, 3 Jan 2017 19:41:16 +0000 (GMT)
Authentication-Results: mx.gnu.org;
       dkim=pass header.i=@gnu.org;
       spf=pass
Message-ID: <abcdef@gnu.org>
From: John Doe <jdoe@gnu.org>
To: Jane Smith <jsmith@gnu.org>

$ sed -E ':a ; $!N ; s/\n\s+/ / ; ta ; P ; D' 2.txt
Subject: Hello World
Content-Type: multipart/alternative; boundary=94eb2c190cc6370f06054535da6a
Date: Tue, 3 Jan 2017 19:41:16 +0000 (GMT)
Authentication-Results: mx.gnu.org; dkim=pass header.i=@gnu.org; spf=pass
Message-ID: <abcdef@gnu.org>
From: John Doe <jdoe@gnu.org>
To: Jane Smith <jsmith@gnu.org>

# A portable (non-gnu) variation:
#   sed -e :a -e '$!N;s/\n  */ /;ta' -e 'P;D'

7.2 センタリング

このスクリプトは全ての行を80カラム幅でセンタリングします。幅を変更するには、'\{…\}'の数を置き換え、追加スペースの数も変更する必要があります。

正規表現内の分かれた部分を一致させるためにbufferコマンドを使用する方法に注意してください。これは一般的なテクニックです。

#!/usr/bin/sed -f

# ホールドスペースに80個の空白を置く
1 {
  x
  s/^$/          /
  s/^.*$/&&&&&&&&/
  x
}

# 先行する空白と末尾の空白を削除
y/TAB/ /
s/^ *//
s/ *$//

# 行の後ろに改行と80個の空白を追加する
G

# 最初の81文字(80 + a newline)のみを残し以降を削除
s/^\(.\{81\}\).*$/\1/

# \2 は残りの空白の半分にマッチし、それを先頭に移動する。
s/^\(.*\)\n\(.*\)\2/\2\1/

7.3 数のインクリメント

このスクリプトは、 sed で算術演算を実行する方法を示すいくつかのうちの1つです。これは確かに可能ですが、手動で行う必要があります。9

数字を1つ増やすには、最後の数字に1を足して次の数字に置き換えます。例外が1つあります。数字が9のときは、9がなくなるまで、前の数字も増分する必要があります。

Bruno Haibleによるこの解法は、単一のバッファを使用するため、非常に巧妙でスマートです。 この制限がない場合は、行番号をつけるで使用されるアルゴリズムのほうが速くなります。末尾の9文字をアンダースコア'_'に置き換えて、そして最後の数字を増やすために複数の s コマンドを使用し、そしてアンダースコア'_'をゼロ'0'に置き換えます。

#!/usr/bin/sed -f

/[^0-9]/ d

# 末尾の9文字をすべて'_'に置き換えます
# (数字以外の任意の文字を使用できます)
:d
s/9\(_*\)$/_\1/
td

# 最後の数字のみ増やします。最初の行は、数字を追加する必要がある場合、
# 最上位桁の1を追加します。

s/^\(_*\)$/1\1/; tn
s/8\(_*\)$/9\1/; tn
s/7\(_*\)$/8\1/; tn
s/6\(_*\)$/7\1/; tn
s/5\(_*\)$/6\1/; tn
s/4\(_*\)$/5\1/; tn
s/3\(_*\)$/4\1/; tn
s/2\(_*\)$/3\1/; tn
s/1\(_*\)$/2\1/; tn
s/0\(_*\)$/1\1/; tn

:n
y/_/0/

7.4 ファイル名を小文字にする

これは sed のかなり奇妙な使い方です。テキストを変換し、それをシェルコマンドに変換してから、単にそれらをシェルに送ります。だがご心配なく。 sed を使用するともっとひどいハックだってあります。私は date の出力を bc プログラムに変換するスクリプトを見たことがあります。

この本体は sed スクリプトで、名前を下から上に(またはその逆に)再マップし、再マップされた名前が元の名前と同じであるかどうかを調べます。スクリプトがシェル変数と適切な引用符を使用してどのようにパラメータ化されるかに注意してください。

#!/bin/sh
# rename files to lower/upper case...
#
# usage:
#    move-to-lower *
#    move-to-upper *
# or
#    move-to-lower -R .
#    move-to-upper -R .
#

help()
{
        cat << eof
Usage: $0 [-n] [-r] [-h] files...

-n      do nothing, only see what would be done
-R      recursive (use find)
-h      this message
files   files to remap to lower case

例:
       $0 -n *        (see if everything is ok, then...)
       $0 *

       $0 -R .

eof
}

apply_cmd='sh'
finder='echo "$@" | tr " " "\n"'
files_only=

while :
do
    case "$1" in
        -n) apply_cmd='cat' ;;
        -R) finder='find "$@" -type f';;
        -h) help ; exit 1 ;;
        *) break ;;
    esac
    shift
done

if [ -z "$1" ]; then
        echo Usage: $0 [-h] [-n] [-r] files...
        exit 1
fi

LOWER='abcdefghijklmnopqrstuvwxyz'
UPPER='ABCDEFGHIJKLMNOPQRSTUVWXYZ'

case `basename $0` in
        *upper*) TO=$UPPER; FROM=$LOWER ;;
        *)       FROM=$UPPER; TO=$LOWER ;;
esac

eval $finder | sed -n '

# remove all trailing slashes
s/\/*$//

# add ./ if there is no path, only a filename
/\//!s/^/.\//

# save path+filename
h

# remove path
s/.*\///

# do conversion only on filename
y/'$FROM'/'$TO'/

# now line contains original path+file, while
# hold space contains the new filename
x

# add converted file name to line, which now contains
# path/file-name\nconverted-file-name
G

# check if converted file name is equal to original file name,
# if it is, do not print anything
/^.*\/\(.*\)\n\1/b

# escape special characters for the shell
s/["$`\\]/\\&/g

# now, transform path/fromfile\n, into
# mv path/fromfile path/tofile and print it
s/^\(.*\/\)\(.*\)\n\(.*\)$/mv "\1\2" "\1\3"/p

' | $apply_cmd

7.5 bashの環境変数をプリント

このスクリプトは、Bourne-shellの set コマンドの出力からシェル関数の定義を取り除きます。

#!/bin/sh

set | sed -n '
:x

# if no occurrence of ‘=()’ print and load next line
/=()/!{ p; b; }
/ () $/!{ p; b; }

# これがFOO = "()"のようなvarである場合に備えて、
# functionsセクションの開始で行を保存する
h

# 次の行に波括弧'{'がある場合、
# 関数の後には何も入っていないので終了します。
n
/^{/ q

# print the old line
x; p

# work on the new line now
x; bx
'

7.6 行の文字を逆順にする

このスクリプトは、行内の文字の位置を逆にするために使用できます。この手法は一度に2文字ずつ移動するため、より直感的な実装よりも高速です。

ラベルの定義の前にある tx コマンドに注意してください。これは t コマンドによってテストされるフラグをリセットするためにしばしば必要とされます。

想像力豊かな読者はこのスクリプトの用途を見つけるでしょう。例として、 banner の出力を元に戻すことが挙げられます。10

#!/usr/bin/sed -f

/../!b

# 行を反転する。ふたつの改行の間に行を埋め込み始める
s/^.*$/\
&\
/

# 最初の文字を最後に移動させる。正規表現は、マーカーの間に
# 0個または1個の文字が入るまでマッチします。
tx
:x
s/\(\n.\)\(.*\)\(.\n\)/\3\2\1/
tx

# 改行マーカーを削除
s/\n//g

7.7 複数行にわたるテキスト検索

この節では、 N および D コマンドを使用して、複数行にわたる連続した単語を検索します。「複数行テクニック」参照

これらの例では、文書内で同じ単語が2回出現することを検出します。

二重の単語を一行内で探すのは、GNU grep を使えば簡単で、それはGNU sed でも同じです。

$ cat two-cities-dup1.txt
It was the best of times,
it was the worst of times,
it was the the age of wisdom,
it was the age of foolishness,

$ grep -E '\b(\w+)\s+\1\b' two-cities-dup1.txt
it was the the age of wisdom,

$ grep -n -E '\b(\w+)\s+\1\b' two-cities-dup1.txt
3:it was the the age of wisdom,

$ sed -En '/\b(\w+)\s+\1\b/p' two-cities-dup1.txt
it was the the age of wisdom,

$ sed -En '/\b(\w+)\s+\1\b/{=;p}' two-cities-dup1.txt
3
it was the the age of wisdom,

二重の単語が2行にまたがる場合、grepsed は行ごとに動作するので、上記の正規表現はそれらを見つけられません。

NDコマンドを使用することで、sedは複数行に正規表現を適用できます(つまり、正規表現はパターンスペースに格納した複数行に作用します)。

$ cat two-cities-dup2.txt
It was the best of times, it was the
worst of times, it was the
the age of wisdom,
it was the age of foolishness,

$ sed -En '{N; /\b(\w+)\s+\1\b/{=;p} ; D}'  two-cities-dup2.txt
3
worst of times, it was the
the age of wisdom,

tr -suniq を使った別の解法については、https://gnu.org/s/coreutils/manual/html_node/Squeezing-and-deleting.htmlのGNU coreutilsマニュアルをご覧ください。


7.8 行の長さを揃える

この節では、Nおよび Dコマンドを使用して複数行にわたる連続した単語を検索し、b コマンドを使用して分岐します。「複数行テクニック」、「分岐とフロー制御」参照。

この(多少工夫された)例は、以下の入力ファイルのテキストのフォーマッティングと行の折り返しを扱います。

$ cat two-cities-mix.txt
It was the best of times, it was
the worst of times, it
was the age of
wisdom,
it
was
the age
of foolishness,

次のプログラムは40文字で行を折り返します。

$ cat wrap40.sed
# outer loop
:x

# 改行と続く次の入力行をパターンスペースに追加
N

# パターンスペース内の全ての改行を削除
s/\n/ /g


# Inner loop
:y

# 最初の40文字の後ろに改行を挿入
s/(.{40,40})/\1\n/

# もしパターンスペースに改行があれば
# (すなわち、前の置換が改行を追加していれば)
/\n/ {
    # パターンスペースには改行があり -
    # 最初の改行までの内容をプリントします。
    P

   # 印刷した文字達と最初の改行を削除します
   s/.*\n//

   # ラベル'y'へ無条件ジャンプ - 内部ループの繰り返し
   by
 }

# パターンスペースに改行が無い - ラベル'x'へ無条件ジャンプ(外部ループ)
# そして次の入力行を読み込む
bx

以下は折り曲げられた出力です。

$ sed -E -f wrap40.sed two-cities-mix.txt
It was the best of times, it was the wor
st of times, it was the age of wisdom, i
t was the age of foolishness,

7.9 ファイルの行の順番を逆順にする

これは、さまざまなUnixコマンドをエミュレートする、まったく役に立たない(それでも面白い)スクリプトのシリーズの始まりです。これは特に tac の動作に似ています。

GNU sed 以外の実装では、このスクリプトはすぐに内部バッファをオーバーフローさせるかもしれません。

#!/usr/bin/sed -nf

#入力のすべての行を反転します。つまり、最初の行が最後になりました...

# 2行目以降、バッファ(前の行をすべて含む)は
# 現在の行に「追加」されるので、順序は逆になります。
1!G

# 最終行に居るなら、作業終了したのです -- 全てをプリントします。
$ p

# すべてを再びバッファに保存する
h

7.10 行番号を付ける

このスクリプトは‘cat -n’を置き換えます。 実際、GNU catとまったく同じフォーマットで出力します。

もちろん、これはまったく役に立ちません。2つの理由があります。1つは誰かが既にC言語で書いためであり、2つ目は、次のBourneシェルスクリプトが同じ目的で使用でき、はるかに高速だからです。

#!/bin/sh
sed -e "=" $@ | sed -e '
  s/^/      /
  N
  s/^ *\(......\)\n/\1  /
'

sedを使用して行番号を印刷し、次にNを使用して2行ずつグループ化します。もちろん、このスクリプトは以下に提示されているものほど多くは教えていません。

インクリメントに使用されるアルゴリズムは両方のバッファーを使用するので、行はできるだけ早く印刷されてから廃棄されます。数字は分割されているので、変更された数字はバッファに入り、変更されていない数字はもう一方に入ります。 変更された桁は(yコマンドを使用して)単一のステップで変更されます。. 次の行の行番号が構成され、ホールドスペースに格納されて、次の反復で使用されます。

#!/usr/bin/sed -nf

# 最初のラインでポンプを吸い込む
x
/^$/ s/^.*$/1/

# パターンの前に正しい行番号を追加
G
h

# Format it and print it
s/^/      /
s/^ *\(......\)\n/\1  /p

# ホールドスペースから行番号を取得
# 次の行に数字を追加する場合0(ゼロ)を追加
g
s/\n.*$//
/^9*$/ s/^/0/

# x によって、変更/未変更の数字を分ける
s/.9*$/x&/

# 変更した数字をホールドスペース内で保持
h
s/^.*x//
y/0123456789/1234567890/
x

# 未変更の数字をパターンスペース内で保持
s/x.*$//

# 新しい番号を作成し、Gが暗黙のうちに追加した改行を削除する
G
s/\n//
h

7.11 空行以外の行に行番号を付ける

' cat -b 'をエミュレートすることは、 ' cat -n 'とほぼ同じです。どの行に番号を付け、どの行に番号を付けないかを選択するだけです。

このスクリプトと前のスクリプトに共通する部分は、 sed スクリプトを正しくコメントすることがどれほど重要かを敢えて示すためにコメント化されていません...

#!/usr/bin/sed -nf

/^$/ {
  p
  b
}

# Same as cat -n from now
x
/^$/ s/^.*$/1/
G
h
s/^/      /
s/^ *\(......\)\n/\1  /p
x
s/\n.*$//
/^9*$/ s/^/0/
s/.9*$/x&/
h
s/^.*x//
y/0123456789/1234567890/
x
s/x.*$//
G
s/\n//
h

7.12 文字数を数える

このスクリプトは sed を使って算術演算を行う別の方法を示しています。この場合、私たちはおそらくもっと大きな数を追加しなければならないので、その実装を連続的なインクリメントで行うのはうまくいきそうにありません(そしておそらくこのスクリプトよりもさらに複雑になります)。

この、別のアプローチは、数字を文字にマッピングすることです。これは、 sed で実装されたそろばんのようなものです。' a 'は1の位の数、 ' b 'は10の位の数などです。現在の行の文字数を1の位の数として追加してから、桁上がり(キャリー)を伝播します。 数十、数百などに。

通常どおり、積算合計はホールドスペースに保持されます。

最終行で、そろばん形式を10進数に戻します。多様性のために、これは80個のsコマンドではなくループで行われます。最初に1の位を変換し、数字から‘a’の並びを削除します。 それから、数十の位が‘a’の並びになるように文字をローテートさせ、文字がなくなるまで続けます。

#!/usr/bin/sed -nf

# Add n+1 a's to hold space (+1 is for the newline)
s/./a/g
H
x
s/\n/a/

# Do the carry.  t's や b's は不要ですが...
# それらによってスピードアップが図れます
t a
: a;  s/aaaaaaaaaa/b/g; t b; b done
: b;  s/bbbbbbbbbb/c/g; t c; b done
: c;  s/cccccccccc/d/g; t d; b done
: d;  s/dddddddddd/e/g; t e; b done
: e;  s/eeeeeeeeee/f/g; t f; b done
: f;  s/ffffffffff/g/g; t g; b done
: g;  s/gggggggggg/h/g; t h; b done
: h;  s/hhhhhhhhhh//g

: done
$!{
  h
  b
}

# 最終行で数字に戻します。

: loop
/a/!s/[b-h]*/&0/
s/aaaaaaaaa/9/
s/aaaaaaaa/8/
s/aaaaaaa/7/
s/aaaaaa/6/
s/aaaaa/5/
s/aaaa/4/
s/aaa/3/
s/aa/2/
s/a/1/

: next
y/bcdefgh/abcdefg/
/[a-h]/ b loop
p

7.13 単語数を数える

このスクリプトは、行の各単語が1つの ‘a’に変換されると、前のスクリプトとほぼ同じになります(前のスクリプトでは、各文字が ‘a’に変更されました)。

本物の wc プログラムが ' wc -c 'のために最適化されたループを持っているのは興味深いですが、それらは文字よりもむしろ単語を数える方がはるかに遅いです。代わりに、このスクリプトのボトルネックは算術演算です。したがって、単語数を数えるほうが速くなります(小さい数を管理する必要はあります)。

繰り返しますが、前のと共通部分は sed スクリプトにコメントすることの重要性を示すために敢えてコメントしていません

#!/usr/bin/sed -nf

# Convert words to a's
s/[ TAB][ TAB]*/ /g
s/^/ /
s/ [^ ][^ ]*/a /g
s/ //g

# Append them to hold space
H
x
s/\n//

# これ以降はwc -cと同じです。
/aaaaaaaaaa/!bx;   s/aaaaaaaaaa/b/g
/bbbbbbbbbb/!bx;   s/bbbbbbbbbb/c/g
/cccccccccc/!bx;   s/cccccccccc/d/g
/dddddddddd/!bx;   s/dddddddddd/e/g
/eeeeeeeeee/!bx;   s/eeeeeeeeee/f/g
/ffffffffff/!bx;   s/ffffffffff/g/g
/gggggggggg/!bx;   s/gggggggggg/h/g
s/hhhhhhhhhh//g
:x
$!{ h; b; }
:y
/a/!s/[b-h]*/&0/
s/aaaaaaaaa/9/
s/aaaaaaaa/8/
s/aaaaaaa/7/
s/aaaaaa/6/
s/aaaaa/5/
s/aaaa/4/
s/aaa/3/
s/aa/2/
s/a/1/
y/bcdefgh/abcdefg/
/[a-h]/ by
p

7.14 行数を数える

sed は私たちに無料で「 wc -l 」機能を提供してくれるので、今回はわざわざ変なことはしていません。見よ!

#!/usr/bin/sed -nf
$=

7.15 最初の数行をプリントする

このスクリプトはおそらく最も簡単で便利な sed スクリプトです。表示される行数は q コマンドの直前までです。

#!/usr/bin/sed -f
10q

7.16 末尾の数行をプリントする

最初の行ではなく最後の n 行を印刷するのは、より複雑だけども可能ではあります。nは、スクリプト2行目の'!'(bang文字)の前に書いてあります(。

このスクリプトは tac スクリプトと似ていますが、最終的な出力をホールドスペースに保持し、最後に出力するという点です。

#!/usr/bin/sed -nf

1!{; H; g; }
1,10 !s/[^\n]*\n//
$p
h

主に、スクリプトは10行のウィンドウを保持し、行を追加して最も古い行を削除することによってそれをスライドさせます(2行目の置換コマンドは D コマンドのように機能しますがループを再開しません)。

「スライディングウィンドウ」技術は、効率的で複雑な sed スクリプトを書くための非常に強力な方法です。なぜなら、手動で実装した場合、 P のようなコマンドは多くの作業を必要とするからです。

NPD コマンドに基づいたテクニックをこの章の残りの部分で十分に紹介するために、ここでは「スライディングウィンドウ」を使ったtailを実装します。

これは複雑に見えますが、実際の作業はさっきのスクリプトと同じです。ただし、適切な行数を入力した後は、行間の状態を維持するためにホールドスペースを使用せず、代わりにND を使用して一行でパターンスペースをスライドします。

#!/usr/bin/sed -f

1h
2,10 {; H; g; }
$q
1,9d
N
D

最初の10行の入力後、1行目、2行目、4行目が非アクティブになっていることに注意してください。その後、スクリプトはすべて、入力の最後の行で終了し、次の入力行をパターンスペースに追加して、最初の行を削除します。


7.17 同一行を1つにまとめる

これは N P 、および D コマンドを使用する技術の例の中で、おそらく習得が最も困難です。

#!/usr/bin/sed -f
h

:b
# On the last line, print and exit
$b
N
/^\(.*\)\n\1$/ {
    # The two lines are identical.  効果を元に戻す - 
    # the n command.
    g
    bb
}

# If the N command had added the last line, print and exit
$b

# The lines are different; print the first and go
# back working on the second.
P
D

ご覧のとおり、 P D を使用して2行のウィンドウを管理しています。このテクニックは、高度な sed スクリプトでよく使われます。


7.18 重複した行のみプリントする。

このスクリプトは、 ' uniq -d 'のように、重複した行だけを出力します。

#!/usr/bin/sed -nf

$b
N
/^\(.*\)\n\1$/ {
    # 重複行の最初の行を印刷する
    s/.*\n//
    p

    # Loop until we get a different line
    :b
    $b
    N
    /^\(.*\)\n\1$/ {
        s/.*\n//
        bb
    }
}

# 最後の行の後に重複を続けることはできません
$b

# 別のものを見つけました。パターンスペース内にほっとく
# そしてトップに戻り、その重複をハンティングする。
D

7.19 重複行を全て取り除く(重複してない行のみプリントする)

このスクリプトは ' uniq -u 'のようにユニークな行だけを印刷します。

#!/usr/bin/sed -f

# 重複行を検索します---それまでは、見つけたものを印刷します。
$b
N
/^\(.*\)\n\1$/ !{
    P
    D
}

:c
# Got two equal lines in pattern space.  
# ファイルの終わりで、単に終了します
$d

# そうでなければ、私たちは N で行を読み続けます。
# find a different one
s/.*\n//
N
/^\(.*\)\n\1$/ {
    bc
}

# 最後の重複行を削除し
# トップへ戻る
D

7.20 連続する空白行を1行の空白行にする

最後の例として、これは複雑さとスピードを増す3つのスクリプトです。これらは「 cat -s 」と同じ機能を実装しています。

最初と最後に既に空行が1行以上会った場合、それぞれ空行1行だけは残さなければなりません。

#!/usr/bin/sed -f

# 空行だったら次の行を連結する
# Note there is a star in the regexp
:x
/^\n*$/ {
N
bx
}

# 今、連続する'\n'を1つにする。無い時は何もしない
# s/^\(\n\)*/\1/ と同等
s/\n*/\
/

これはもう少し複雑で、最初に空の行をすべて削除します。最後に1行の空白行があったとしても、それは残ります。

#!/usr/bin/sed -f

# 先行する全ての空行を削除
1,/^./{
/./!d
}

# 空行であればそれを削除し、
# それに続く空行も同じです。
:x
/./!{
N
s/^\n$//
tx
}

これは先導する空行達と後続する空行達を削除します。それも最速です。ループは n b で全部処理され、各行末で次のサイクルに移る通常の自動的な動作が全くありません。

#!/usr/bin/sed -nf

# 全ての(先導する)空白を削除
/./!d

# ここに居る、すなわち空でない
:x
# それをプリント
p
# 次の入力行を得る
n
# 文字(列)があった?なら再びそれをプリントして, etc...
/./bx

# 文字が無かった。つまり空行を得た
:z
# 次を読み込んで、ここが最終行の場合は、
# 後続の空行達は書き込みません
n
# 空かな?ならばそれを無視、そして次を取得...
# 全ての空行を削除
/./!bz

# 全ての空行は削除/無視した。全く無くなった。しかし我々は空にしたい訳じゃない
# 我々は圧縮(squeeze)したいのだ。よって露骨に空行を挿入する。
i\

bx

8 GNU sedの制限と、GNU sedで撤廃された制限

移植可能な sed スクリプトを書きたいという人は、(パターンスペースとホールドスペースのための)行の長さを4000バイト以下に制限する実装があることに注意してください。 POSIX 規格では、準拠した sed の実装で少なくとも8192バイトの行の長さをサポートすることを規定しています。GNU sed には行の長さに関する制限は組み込まれていません。 より多くの(仮想)メモリをmalloc()できれば、好きなだけ行を注ぎ込んだり構築したりすることができます。

ただし、再帰はサブパターンと不定の繰り返しを処理するために使用されます。これは、利用可能なスタックスペースが、特定のパターンで処理できるバッファのサイズを制限する可能性があることを意味します。


9 sedを習得するためのこの文書以外の資料

GNU sed の最新情報についてはこちら。https://www.gnu.org/software/sed/

一般的な質問や提案の送り先: sed-devel@gnu.org(訳注:このMLに参加するには https://lists.gnu.org/mailman/listinfo/sed-devel のページ従って操作すると自分宛てに確認メールが届くのでそれに従って下さい)。過去の議論のメーリングリストアーカイブはこちら。https://lists.gnu.org/archive/html/sed-devel/.

以下、 sed (GNU sed とその他のバリエーションの両方)に関する資料ですこれらはGNU sed 開発者によって保守されていないことに注意してください。


10バグ報告

バグ報告はこちらへ(もちろん英語で) bug-sed@gnu.org. また、可能なかぎり報告本文に‘sed --version’の出力を含めて下さい。

以下のようなバグレポートは送らないでください。

while building frobme-1.3.4
$ configure
error→ sed: file sedscr line 1: Unknown option to 's'

もしGNU sed があなたのお気に入りのパッケージを設定しないならば、特定の問題を識別して、独立したテストケースを作るために数分余分に時間をかけてください。Cコンパイラのような他のプログラムとは異なり、 sed のためのそのようなテストケースを作ることは非常に簡単です。

独立したテストケースには、テストを実行するために必要なすべてのデータと、問題を引き起こす sed の特定の呼び出しを含めます。独立したテストケースは短いほどいいです。テストケースの sed から「frobme-1.3.4を設定してみてください」というようなものを削除してはいけません。もちろん、それは基礎的なバグを探すのには十分な情報ですが、それは非常に役立つ技術情報というわけではありません。

なお以下は俗に言う「既知のバグ」であって、再度再度報告して頂くようなバグではありません。

最終行でのN コマンドの振る舞い

sed のほとんどのバージョンは、ファイルの最後の行で N コマンドが発行されると、何も表示せずに終了します。 -n コマンドラインオプションが指定されていない限り、GNU sed は終了する前にパターンスペースを表示します。この選択は仕様によるものです。

デフォルトの動作(GNU拡張、非POSIX準拠):

$ seq 3 | sed N
1
2
3

POSIX準拠の動作を強制:

$ seq 3 | sed --posix N
1
2

たとえば、次の振る舞い

sed N foo bar

は、fooの行数が偶数か奇数かに依存します。12. また、パターンマッチの後に続く数行を読むためのスクリプトを書くとき、伝統的な実装の sed はあなたに次のようなものを書くことを強いるでしょう。

/foo/{ $!N; $!N; $!N; $!N; $!N; $!N; $!N; $!N; $!N }

GNU sedでは代わりに次のように書ける

/foo/{ N;N;N;N;N;N;N;N;N; }

いずれにせよ、最も簡単な回避策は、従来の振る舞いに依存するスクリプトで $ d; N を使うか、または POSIXLY_CORRECT 変数を空でない値に設定することです。

正規表現文法破壊(バックスラッシュ問題)

sedPOSIX 基本正規表現文法を使います。規格によると、いくつかのエスケープシーケンスの意味はこの文法では定義されていません。 sed の場合、\|\+\?\`\'\<\>\b\B\w\W です。

POSIX 基本正規表現を使用するすべてのGNUプログラムと同様に、 sed はこれらのエスケープシーケンスを特殊文字として解釈します。x\+ は、1つまたはそれ以上現れる‘x’にマッチします。. abc\|def は‘abc’または‘def’のいずれかにマッチします。

これらの文法が問題を引き起こすのは他のsedの為に書かれたスクリプトを実行するときです。いくつかのsed プログラムは \|\+ は 文字|+ するものだと決めつけています。このようなスクリプトは、GNU sed のような現代的な sed の実装で使用する場合には、誤ったバックスラッシュを削除して修正する必要があります。

一方、スクリプトによっては s|abc\|def||g を使用して、abcまたはdefどちらかの出現を削除します。これは sed 4.0.xまでは機能しましたが、新しいバージョンではabc|defという文字列を削除するものとして解釈されます。POSIXによれば、これもまた未定義の振る舞いであり、この解釈は間違いなくより健全(robust)です。例えば、より古いsedでは、スラッシュをエスケープする一般的なケースでは正規表現照合プログラムが \//として解析する必要がありました。 新しい振る舞いはこれを避けています、そしてこれは良いことです。正規表現マッチ機構は部分的にしか私たちの管理下にないからです。

さらに、このバージョンの sed では、スクリプトに印刷不可能な文字を挿入するための複数のエスケープ文字(そのうちのいくつかは複数文字)がサポートされています(\a, \c, \d, \o, \r, \t, \v, \x)。これらも他の sed 用に書かれたスクリプトで同様の問題を引き起こす可能性があります。

-i が読み込み専用ファイルを壊す問題

要するに、 ' sed -i 'を指定すると、読み取り専用ファイルの内容を削除できます。一般に、 -i オプション(起動を参照)を使用すると、保護されているファイルを破壊できます。これはバグではなく、むしろUnixファイルシステムがどのように機能するかの結果です。

ファイルに対する許可は、そのファイル内のデータに何が起こり得るかを示し、ディレクトリに対する許可は、そのディレクトリ内のファイルのリストに何が起こりうるかを示します。' sed -i 'はすでにディスク上にあるファイルを書き込むために開くことはありません。そうではなく、一時的なファイルに対して操作し最終的に元の名前に変更されます。ファイルの名前を変更または削除すると、実際にはディレクトリの内容が変更されるため、操作はファイルの権限ではなくディレクトリの権限に依存します。 同じ理由で、 sed は読み取り専用ディレクトリの書き込み可能なファイルに '-i'を使用させず、 '-i'がそのようなファイルに使用されるとハードリンクまたはシンボリックリンクを解除します。

0a が動作しない(エラーになる)問題

行番号0の行は存在しません。0は、スクリプトの起動時に 0,/RE/のようなアドレスをアクティブとして扱うためだけに使用される特殊なアドレスです。 1,/abc/dと書き、最初の行に ‘abc’という単語が含まれていると、アドレス範囲は少なくとも2行にわたる必要があるため(ファイルの終わりを除く)、その一致は無視されます。 しかし、おそらくあなたが望んでいたのは ‘abc’を含む最初の行まですべての行を削除することです。これは 0,/abc/dで得られます。

[a-z] が大文字小文字を区別しない問題

あなたはロケールに関する問題に遭遇しています。POSIXは[a-z] に現在のロケールの照合順序を使用することを強制しています。C言語で言えば strcmp(3)の代わりにstrcoll(3)を使用することを意味します。大/小文字を区別しない照合順を持つロケールもあれば、そうでないロケールもあります。

別の問題は、[a-z] が照合記号を使おうとしていることです。これは、GNU sedを提供しているものをコンパイルするのではなく、GNU libcの正規表現マッチャーを使用して、GNUシステムを使用している場合にのみ発生します。たとえば、デンマーク語のロケールでは、正規表現 ^[a-z]$は文字列 ‘aa’と一致します。これは、 ‘a’の後で、 ‘b’の前にある単一の照合記号だからです。 ‘ll’はスペイン語のロケールでも‘ij’のオランダ語のロケールでも同じように動作します。

シェルスクリプトでバグを引き起こす可能性があるこれらの問題を回避するには、 LC_COLLATE および LC_CTYPE 環境変数を ‘C’に設定してください。

s/.*// がパターンスペースを全削除しない問題

これは入力ストリームが不正なマルチバイトつづりを含んでいると発生します。POSIXは、そのようなシーケンスは ‘.’と一致しないことを強制しているので、 ‘s/.*//’はあなたが期待するようにパターンスペースを全削除しないでしょう。実際、ほとんどのマルチバイトロケール(UTF-8ロケールを含む)では、スクリプトの途中でsedのバッファを全削除することはできません。このため、GNU sed では、(zap用の)zコマンドが拡張機能として提供されています。

シェルスクリプトでバグを引き起こす可能性があるこれらの問題を回避するには、 LC_COLLATE および LC_CTYPE 環境変数を ‘C’に設定してください。


Appendix A GNU Free Documentation License

Version 1.3, 3 November 2008
Copyright © 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc.
https://fsf.org/

Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
  1. PREAMBLE

    The purpose of this License is to make a manual, textbook, or other functional and useful document free in the sense of freedom: to assure everyone the effective freedom to copy and redistribute it, with or without modifying it, either commercially or noncommercially. Secondarily, this License preserves for the author and publisher a way to get credit for their work, while not being considered responsible for modifications made by others.

    This License is a kind of “copyleft”, which means that derivative works of the document must themselves be free in the same sense. It complements the GNU General Public License, which is a copyleft license designed for free software.

    We have designed this License in order to use it for manuals for free software, because free software needs free documentation: a free program should come with manuals providing the same freedoms that the software does. But this License is not limited to software manuals; it can be used for any textual work, regardless of subject matter or whether it is published as a printed book. We recommend this License principally for works whose purpose is instruction or reference.

  2. APPLICABILITY AND DEFINITIONS

    This License applies to any manual or other work, in any medium, that contains a notice placed by the copyright holder saying it can be distributed under the terms of this License. Such a notice grants a world-wide, royalty-free license, unlimited in duration, to use that work under the conditions stated herein. The “Document”, below, refers to any such manual or work. Any member of the public is a licensee, and is addressed as “you”. You accept the license if you copy, modify or distribute the work in a way requiring permission under copyright law.

    A “Modified Version” of the Document means any work containing the Document or a portion of it, either copied verbatim, or with modifications and/or translated into another language.

    A “Secondary Section” is a named appendix or a front-matter section of the Document that deals exclusively with the relationship of the publishers or authors of the Document to the Document’s overall subject (or to related matters) and contains nothing that could fall directly within that overall subject. (Thus, if the Document is in part a textbook of mathematics, a Secondary Section may not explain any mathematics.) The relationship could be a matter of historical connection with the subject or with related matters, or of legal, commercial, philosophical, ethical or political position regarding them.

    The “Invariant Sections” are certain Secondary Sections whose titles are designated, as being those of Invariant Sections, in the notice that says that the Document is released under this License. If a section does not fit the above definition of Secondary then it is not allowed to be designated as Invariant. The Document may contain zero Invariant Sections. If the Document does not identify any Invariant Sections then there are none.

    The “Cover Texts” are certain short passages of text that are listed, as Front-Cover Texts or Back-Cover Texts, in the notice that says that the Document is released under this License. A Front-Cover Text may be at most 5 words, and a Back-Cover Text may be at most 25 words.

    A “Transparent” copy of the Document means a machine-readable copy, represented in a format whose specification is available to the general public, that is suitable for revising the document straightforwardly with generic text editors or (for images composed of pixels) generic paint programs or (for drawings) some widely available drawing editor, and that is suitable for input to text formatters or for automatic translation to a variety of formats suitable for input to text formatters. A copy made in an otherwise Transparent file format whose markup, or absence of markup, has been arranged to thwart or discourage subsequent modification by readers is not Transparent. An image format is not Transparent if used for any substantial amount of text. A copy that is not “Transparent” is called “Opaque”.

    Examples of suitable formats for Transparent copies include plain ASCII without markup, Texinfo input format, LaTeX input format, SGML or XML using a publicly available DTD, and standard-conforming simple HTML, PostScript or PDF designed for human modification. Examples of transparent image formats include PNG, XCF and JPG. Opaque formats include proprietary formats that can be read and edited only by proprietary word processors, SGML or XML for which the DTD and/or processing tools are not generally available, and the machine-generated HTML, PostScript or PDF produced by some word processors for output purposes only.

    The “Title Page” means, for a printed book, the title page itself, plus such following pages as are needed to hold, legibly, the material this License requires to appear in the title page. For works in formats which do not have any title page as such, “Title Page” means the text near the most prominent appearance of the work’s title, preceding the beginning of the body of the text.

    The “publisher” means any person or entity that distributes copies of the Document to the public.

    A section “Entitled XYZ” means a named subunit of the Document whose title either is precisely XYZ or contains XYZ in parentheses following text that translates XYZ in another language. (Here XYZ stands for a specific section name mentioned below, such as “Acknowledgements”, “Dedications”, “Endorsements”, or “History”.) To “Preserve the Title” of such a section when you modify the Document means that it remains a section “Entitled XYZ” according to this definition.

    The Document may include Warranty Disclaimers next to the notice which states that this License applies to the Document. These Warranty Disclaimers are considered to be included by reference in this License, but only as regards disclaiming warranties: any other implication that these Warranty Disclaimers may have is void and has no effect on the meaning of this License.

  3. VERBATIM COPYING

    You may copy and distribute the Document in any medium, either commercially or noncommercially, provided that this License, the copyright notices, and the license notice saying this License applies to the Document are reproduced in all copies, and that you add no other conditions whatsoever to those of this License. You may not use technical measures to obstruct or control the reading or further copying of the copies you make or distribute. However, you may accept compensation in exchange for copies. If you distribute a large enough number of copies you must also follow the conditions in section 3.

    You may also lend copies, under the same conditions stated above, and you may publicly display copies.

  4. COPYING IN QUANTITY

    If you publish printed copies (or copies in media that commonly have printed covers) of the Document, numbering more than 100, and the Document’s license notice requires Cover Texts, you must enclose the copies in covers that carry, clearly and legibly, all these Cover Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on the back cover. Both covers must also clearly and legibly identify you as the publisher of these copies. The front cover must present the full title with all words of the title equally prominent and visible. You may add other material on the covers in addition. Copying with changes limited to the covers, as long as they preserve the title of the Document and satisfy these conditions, can be treated as verbatim copying in other respects.

    If the required texts for either cover are too voluminous to fit legibly, you should put the first ones listed (as many as fit reasonably) on the actual cover, and continue the rest onto adjacent pages.

    If you publish or distribute Opaque copies of the Document numbering more than 100, you must either include a machine-readable Transparent copy along with each Opaque copy, or state in or with each Opaque copy a computer-network location from which the general network-using public has access to download using public-standard network protocols a complete Transparent copy of the Document, free of added material. If you use the latter option, you must take reasonably prudent steps, when you begin distribution of Opaque copies in quantity, to ensure that this Transparent copy will remain thus accessible at the stated location until at least one year after the last time you distribute an Opaque copy (directly or through your agents or retailers) of that edition to the public.

    It is requested, but not required, that you contact the authors of the Document well before redistributing any large number of copies, to give them a chance to provide you with an updated version of the Document.

  5. MODIFICATIONS

    You may copy and distribute a Modified Version of the Document under the conditions of sections 2 and 3 above, provided that you release the Modified Version under precisely this License, with the Modified Version filling the role of the Document, thus licensing distribution and modification of the Modified Version to whoever possesses a copy of it. In addition, you must do these things in the Modified Version:

    1. Use in the Title Page (and on the covers, if any) a title distinct from that of the Document, and from those of previous versions (which should, if there were any, be listed in the History section of the Document). You may use the same title as a previous version if the original publisher of that version gives permission.
    2. List on the Title Page, as authors, one or more persons or entities responsible for authorship of the modifications in the Modified Version, together with at least five of the principal authors of the Document (all of its principal authors, if it has fewer than five), unless they release you from this requirement.
    3. State on the Title page the name of the publisher of the Modified Version, as the publisher.
    4. Preserve all the copyright notices of the Document.
    5. Add an appropriate copyright notice for your modifications adjacent to the other copyright notices.
    6. Include, immediately after the copyright notices, a license notice giving the public permission to use the Modified Version under the terms of this License, in the form shown in the Addendum below.
    7. Preserve in that license notice the full lists of Invariant Sections and required Cover Texts given in the Document’s license notice.
    8. Include an unaltered copy of this License.
    9. Preserve the section Entitled “History”, Preserve its Title, and add to it an item stating at least the title, year, new authors, and publisher of the Modified Version as given on the Title Page. If there is no section Entitled “History” in the Document, create one stating the title, year, authors, and publisher of the Document as given on its Title Page, then add an item describing the Modified Version as stated in the previous sentence.
    10. Preserve the network location, if any, given in the Document for public access to a Transparent copy of the Document, and likewise the network locations given in the Document for previous versions it was based on. These may be placed in the “History” section. You may omit a network location for a work that was published at least four years before the Document itself, or if the original publisher of the version it refers to gives permission.
    11. For any section Entitled “Acknowledgements” or “Dedications”, Preserve the Title of the section, and preserve in the section all the substance and tone of each of the contributor acknowledgements and/or dedications given therein.
    12. Preserve all the Invariant Sections of the Document, unaltered in their text and in their titles. Section numbers or the equivalent are not considered part of the section titles.
    13. Delete any section Entitled “Endorsements”. Such a section may not be included in the Modified Version.
    14. Do not retitle any existing section to be Entitled “Endorsements” or to conflict in title with any Invariant Section.
    15. Preserve any Warranty Disclaimers.

    If the Modified Version includes new front-matter sections or appendices that qualify as Secondary Sections and contain no material copied from the Document, you may at your option designate some or all of these sections as invariant. To do this, add their titles to the list of Invariant Sections in the Modified Version’s license notice. These titles must be distinct from any other section titles.

    You may add a section Entitled “Endorsements”, provided it contains nothing but endorsements of your Modified Version by various parties—for example, statements of peer review or that the text has been approved by an organization as the authoritative definition of a standard.

    You may add a passage of up to five words as a Front-Cover Text, and a passage of up to 25 words as a Back-Cover Text, to the end of the list of Cover Texts in the Modified Version. Only one passage of Front-Cover Text and one of Back-Cover Text may be added by (or through arrangements made by) any one entity. If the Document already includes a cover text for the same cover, previously added by you or by arrangement made by the same entity you are acting on behalf of, you may not add another; but you may replace the old one, on explicit permission from the previous publisher that added the old one.

    The author(s) and publisher(s) of the Document do not by this License give permission to use their names for publicity for or to assert or imply endorsement of any Modified Version.

  6. COMBINING DOCUMENTS

    You may combine the Document with other documents released under this License, under the terms defined in section 4 above for modified versions, provided that you include in the combination all of the Invariant Sections of all of the original documents, unmodified, and list them all as Invariant Sections of your combined work in its license notice, and that you preserve all their Warranty Disclaimers.

    The combined work need only contain one copy of this License, and multiple identical Invariant Sections may be replaced with a single copy. If there are multiple Invariant Sections with the same name but different contents, make the title of each such section unique by adding at the end of it, in parentheses, the name of the original author or publisher of that section if known, or else a unique number. Make the same adjustment to the section titles in the list of Invariant Sections in the license notice of the combined work.

    In the combination, you must combine any sections Entitled “History” in the various original documents, forming one section Entitled “History”; likewise combine any sections Entitled “Acknowledgements”, and any sections Entitled “Dedications”. You must delete all sections Entitled “Endorsements.”

  7. COLLECTIONS OF DOCUMENTS

    You may make a collection consisting of the Document and other documents released under this License, and replace the individual copies of this License in the various documents with a single copy that is included in the collection, provided that you follow the rules of this License for verbatim copying of each of the documents in all other respects.

    You may extract a single document from such a collection, and distribute it individually under this License, provided you insert a copy of this License into the extracted document, and follow this License in all other respects regarding verbatim copying of that document.

  8. AGGREGATION WITH INDEPENDENT WORKS

    A compilation of the Document or its derivatives with other separate and independent documents or works, in or on a volume of a storage or distribution medium, is called an “aggregate” if the copyright resulting from the compilation is not used to limit the legal rights of the compilation’s users beyond what the individual works permit. When the Document is included in an aggregate, this License does not apply to the other works in the aggregate which are not themselves derivative works of the Document.

    If the Cover Text requirement of section 3 is applicable to these copies of the Document, then if the Document is less than one half of the entire aggregate, the Document’s Cover Texts may be placed on covers that bracket the Document within the aggregate, or the electronic equivalent of covers if the Document is in electronic form. Otherwise they must appear on printed covers that bracket the whole aggregate.

  9. TRANSLATION

    Translation is considered a kind of modification, so you may distribute translations of the Document under the terms of section 4. Replacing Invariant Sections with translations requires special permission from their copyright holders, but you may include translations of some or all Invariant Sections in addition to the original versions of these Invariant Sections. You may include a translation of this License, and all the license notices in the Document, and any Warranty Disclaimers, provided that you also include the original English version of this License and the original versions of those notices and disclaimers. In case of a disagreement between the translation and the original version of this License or a notice or disclaimer, the original version will prevail.

    If a section in the Document is Entitled “Acknowledgements”, “Dedications”, or “History”, the requirement (section 4) to Preserve its Title (section 1) will typically require changing the actual title.

  10. TERMINATION

    You may not copy, modify, sublicense, or distribute the Document except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, or distribute it is void, and will automatically terminate your rights under this License.

    However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation.

    Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.

    Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, receipt of a copy of some or all of the same material does not give you any rights to use it.

  11. FUTURE REVISIONS OF THIS LICENSE

    The Free Software Foundation may publish new, revised versions of the GNU Free Documentation License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. See https://www.gnu.org/copyleft/.

    Each version of the License is given a distinguishing version number. If the Document specifies that a particular numbered version of this License “or any later version” applies to it, you have the option of following the terms and conditions either of that specified version or of any later version that has been published (not as a draft) by the Free Software Foundation. If the Document does not specify a version number of this License, you may choose any version ever published (not as a draft) by the Free Software Foundation. If the Document specifies that a proxy can decide which future versions of this License can be used, that proxy’s public statement of acceptance of a version permanently authorizes you to choose that version for the Document.

  12. RELICENSING

    “Massive Multiauthor Collaboration Site” (or “MMC Site”) means any World Wide Web server that publishes copyrightable works and also provides prominent facilities for anybody to edit those works. A public wiki that anybody can edit is an example of such a server. A “Massive Multiauthor Collaboration” (or “MMC”) contained in the site means any set of copyrightable works thus published on the MMC site.

    “CC-BY-SA” means the Creative Commons Attribution-Share Alike 3.0 license published by Creative Commons Corporation, a not-for-profit corporation with a principal place of business in San Francisco, California, as well as future copyleft versions of that license published by that same organization.

    “Incorporate” means to publish or republish a Document, in whole or in part, as part of another Document.

    An MMC is “eligible for relicensing” if it is licensed under this License, and if all works that were first published under this License somewhere other than this MMC, and subsequently incorporated in whole or in part into the MMC, (1) had no cover texts or invariant sections, and (2) were thus incorporated prior to November 1, 2008.

    The operator of an MMC Site may republish an MMC contained in the site under CC-BY-SA on the same site at any time before August 1, 2009, provided the MMC is eligible for relicensing.

ADDENDUM: How to use this License for your documents

To use this License in a document you have written, include a copy of the License in the document and put the following copyright and license notices just after the title page:

  Copyright (C)  year  your name.
  Permission is granted to copy, distribute and/or modify this document
  under the terms of the GNU Free Documentation License, Version 1.3
  or any later version published by the Free Software Foundation;
  with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
  Texts.  A copy of the license is included in the section entitled ``GNU
  Free Documentation License''.

If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts, replace the “with…Texts.” line with this:

    with the Invariant Sections being list their titles, with
    the Front-Cover Texts being list, and with the Back-Cover Texts
    being list.

If you have Invariant Sections without Cover Texts, or some other combination of the three, merge those two alternatives to suit the situation.

If your document contains nontrivial examples of program code, we recommend releasing these examples in parallel under your choice of free software license, such as the GNU General Public License, to permit their use in free software.


概念索引

これはsedコマンドとコマンドラインオプションの例外を除く、この文書で述べた全ての話題の索引です。

Jump to:   -   0   ;  
A   B   C   D   E   F   G   H   I   J   L   M   N   O   P   Q   R   S   T   U   V   W   X   Z  
索引見出し  掲載節

-
-e とその例:  概要
-e とその例: sedスクリプト概要
–expression とその例:  概要
-f とその例:  概要
-f とその例: sedスクリプト概要
–file とその例:  概要
-i とその例:  概要
-n とその例:  概要
-s とその例:  概要

0
0 (ゼロ)アドレス: バグ報告

;
;, コマンド区切り: sedスクリプト概要

A
a, and semicolons(';') sedスクリプト概要
Additional reading about sed(sedについての追加の読み物): この文書以外の資料
addr1,+N:  範囲アドレス
addr1,~N:  範囲アドレス
address range, example(アドレス範囲とその例): sedスクリプト概要
Address, as a regular expression: 正規表現アドレス
Address, last line(アドレス、最終行): 数値指定アドレス
Address, numeric: 数値指定アドレス
addresses, excluding(範囲「外」アドレス):  アドレス概要
Addresses, in sed scripts(sedスクリプトのアドレス): 数値指定アドレス
addresses, negating(アドレス、その否定形):  アドレス概要
addresses, numeric(数値指定アドレス):  アドレス概要
addresses, range(範囲指定アドレス):  アドレス概要
addresses, regular expression(正規表現アドレス):  アドレス概要
addresses, syntax(アドレス、その文法): sedスクリプト概要
alphabetic characters(英字):  文字クラスと角括弧式
alphanumeric characters(英数字):  文字クラスと角括弧式
Append hold space to pattern space(パターンスペースにホールドスペースを追加): 他のコマンド
Append next input line to pattern space(パターンスペースに次の入力行を追加する): 他のコマンド
Append pattern space to hold space(パターンスペースをホールドスペースに追加): 他のコマンド
Appending text after a line(行の後ろにテキストを追加する): 他のコマンド

B
b, joining lines with(線をつなぐ): 分岐とフロー制御
b, versus t(b V.S. t): 分岐とフロー制御
back-reference(後方参照):  後方参照と部分式
Backreferences, in regular expressions(正規表現中の後方参照): The "s" Command
blank characters(空白文字):  文字クラスと角括弧式
bracket expression(ブラケット '['...']'表現):  文字クラスと角括弧式
Branch to a label, if s/// failed(s/// コマンドが失敗したら指定のラベルに飛ぶ): 拡張コマンド達
Branch to a label, if s/// succeeded('s///'が成功したら指定のラベルへ分岐する。: プログラミングコマンド
Branch to a label, unconditionally(無条件にラベルに飛ぶ): プログラミングコマンド
branching and n, N(分岐と n, N): 分岐とフロー制御
branching, infinite loop(分岐と無限ループ): 分岐とフロー制御
branching, joining lines(分岐と行連結): 分岐とフロー制御
Buffer spaces, pattern and hold(パターンスペースとホールドスペース): 実行サイクル
Bugs, reporting(報告されているバグ): バグ報告

C
c, and semicolons(cコマンドとセミコロン';'): sedスクリプト概要
case insensitive, regular expression(正規表現での大文字小文字の取扱い): 正規表現アドレス
Case-insensitive matching(大文字小文字区別しない正規表現マッチング): The "s" Command
Caveat — #n on first line(最初の行のコメント'#n'による「差し止め」): 一般コマンド達
character class(文字クラス):  文字クラスと角括弧式
character classes(文字クラス):  文字クラスと角括弧式
classes of characters(文字クラス):  文字クラスと角括弧式
Command groups(グループ化'{'...'}'): 一般コマンド達
Comments, in scripts(スクリプト内のコマンド): 一般コマンド達
Conditional branch(条件分岐): プログラミングコマンド
Conditional branch(条件分岐): 拡張コマンド達
control characters(制御文字):  文字クラスと角括弧式
Copy hold space into pattern space(ホールドスペースをパターンスペースにコピーする): 他のコマンド
Copy pattern space into hold space(パターンスペースをホールドスペースにコピーする): 他のコマンド
cycle, restarting(次のサイクルの開始): 分岐とフロー制御

D
dとその例: sedスクリプト概要
Delete first line from pattern space(パターンスペース内の最初の行を削除する): 他のコマンド
digit characters(数字):  文字クラスと角括弧式
Disabling autoprint, from command line(コマンドラインからの指定でサイクル間の自動プリントを無効にする):  コマンドラインオプション

E
empty regular expression(空の正規表現'//'): 正規表現アドレス
Emptying pattern space(パターンスペースの内容を空にする): 拡張コマンド達
Emptying pattern space(パターンスペースの内容を空にする): バグ報告
Evaluate Bourne-shell commands(eval bashコマンド): 拡張コマンド達
Evaluate Bourne-shell commands, after substitution(置換後の eval bash コマンド): The "s" Command
example, address range(アドレス範囲例): sedスクリプト概要
example, regular expression(正規表現例): sedスクリプト概要
Exchange hold space with pattern space(ホールドスペースの内容とパターンスペースの内容を交換): 他のコマンド
Excluding lines(指定行「以外」):  アドレス概要
exit status(終了ステータス):  終了ステータス
exit statusとその例:  終了ステータス
Extended regular expressions, choosing(拡張正規表現とそれによる選択):  コマンドラインオプション
Extended regular expressions, syntax(拡張正規表現とその文法): ERE文法

F
File name, printing(現在の入力ファイル名をプリント): 拡張コマンド達
Files to be processed as input(入力として処理されるファイル):  コマンドラインオプション
Flow of control in scripts(スクリプト内のフロー制御): プログラミングコマンド

G
Global substitution(包括的な置換): The "s" Command
GNU拡張:/dev/stderr ファイル指定: The "s" Command
GNU拡張:/dev/stderr ファイル指定: 他のコマンド
GNU拡張: /dev/stdin ファイル指定: 他のコマンド
GNU拡張: /dev/stdin ファイル指定: 拡張コマンド達
GNU 拡張: /dev/stdout ファイル指定:  コマンドラインオプション
GNU 拡張: /dev/stdout ファイル指定: The "s" Command
GNU 拡張: /dev/stdout ファイル指定: 他のコマンド
GNU 拡張: 0(ゼロ)アドレス:  範囲アドレス
GNU 拡張: 0(ゼロ)アドレス: バグ報告
GNU 拡張: 0,addr2 範囲アドレス指定:  範囲アドレス
GNU 拡張: addr1,+N 範囲アドレス指定:  範囲アドレス
GNU 拡張: addr1,~N アドレス指定:  範囲アドレス
GNU 拡張: branch if s/// failed: 拡張コマンド達
GNU 拡張: case modifiers in s commands(sコマンドでの大文字小文字変換): The "s" Command
GNU 拡張: checking for their presence(sedがGNU拡張使えるかどうかチェック): 拡張コマンド達
GNU 拡張: debug:  コマンドラインオプション
GNU 拡張: disabling(GNU拡張を無効にする):  コマンドラインオプション
GNU 拡張: emptying pattern space(パターンスペースを空にする): 拡張コマンド達
GNU 拡張: emptying pattern space(パターンスペースを空にする): バグ報告
GNU 拡張: evaluating Bourne-shell commands(eval bashコマンド): The "s" Command
GNU 拡張: evaluating Bourne-shell commands(eval bashコマンド): 拡張コマンド達
GNU 拡張: extended regular expressions(拡張正規表現):  コマンドラインオプション
GNU 拡張: g and number modifier: The "s" Command
GNU extensions, I modifier: The "s" Command
GNU extensions, I modifier: 正規表現アドレス
GNU拡張, in-place editing(入力ファイル書き換え):  コマンドラインオプション
GNU拡張, in-place editing(入力ファイル書き換え): バグ報告
GNU拡張, M modifier: The "s" Command
GNU拡張, M modifier: 正規表現アドレス
GNU拡張, modifiers and the empty regular expression(空の正規表現とフラグ): 正規表現アドレス
GNU拡張, ‘n~m’ アドレス: 数値指定アドレス
GNU拡張, quitting silently: 拡張コマンド達
GNU拡張, R コマンド: 拡張コマンド達
GNU拡張, reading a file a line at a time: 拡張コマンド達
GNU拡張, returning an exit code: 一般コマンド達
GNU拡張, returning an exit code: 拡張コマンド達
GNU拡張, setting line length: 他のコマンド
GNU拡張, special escapes: エスケープ
GNU拡張, special escapes: バグ報告
GNU拡張, special two-address forms:  範囲アドレス
GNU拡張, subprocesses:(正規表現部分式) The "s" Command
GNU拡張, subprocesses:(正規表現部分式) 拡張コマンド達
GNU拡張, to basic regular expressions: BRE文法
GNU拡張, to basic regular expressions: BRE文法
GNU拡張, to basic regular expressions: BRE文法
GNU拡張, to basic regular expressions: BRE文法
GNU拡張, to basic regular expressions: BRE文法
GNU拡張, to basic regular expressions: バグ報告
GNU拡張, two addresses supported by most commands: 他のコマンド
GNU拡張, two addresses supported by most commands: 他のコマンド
GNU拡張, two addresses supported by most commands: 他のコマンド
GNU拡張, two addresses supported by most commands: 他のコマンド
GNU拡張, unlimited line length: 制限
GNU拡張, writing first line to a file: 拡張コマンド達
Goto, in scripts: プログラミングコマンド
graphic characters(グラフィックキャラクタとは):  文字クラスと角括弧式
Greedy regular expression matching(正規表現の貪欲マッチング): BRE文法
Grouping commands(sedコマンドのグループ化): 一般コマンド達

H
hexadecimal digits(16進数):  文字クラスと角括弧式
Hold space, appending from pattern space: 他のコマンド
Hold space, appending to pattern space: 他のコマンド
Hold space, copy into pattern space: 他のコマンド
Hold space, copying pattern space into: 他のコマンド
Hold space, definition(ホールドスペースとは): 実行サイクル
Hold space, exchange with pattern space: 他のコマンド

I
i, and semicolons(';'): sedスクリプト概要
In-place editing(入力ファイル書き換え): バグ報告
In-place editing, activating(その内部動作):  コマンドラインオプション
In-place editing, Perl-style backup file names:  コマンドラインオプション
infinite loop, branching(無限ループ、分岐): 分岐とフロー制御
Inserting text before a line: 他のコマンド

J
joining lines with branching(行連結と分岐): 分岐とフロー制御
joining quoted-printable lines: 分岐とフロー制御

L
labels: 分岐とフロー制御
Labels, in scripts: プログラミングコマンド
Last line, selecting: 数値指定アドレス
Line length, setting:  コマンドラインオプション
Line length, setting: 他のコマンド
Line number, printing: 他のコマンド
Line selection: 数値指定アドレス
Line, selecting by number: 数値指定アドレス
Line, selecting by regular expression match: 正規表現アドレス
Line, selecting last: 数値指定アドレス
List pattern space: 他のコマンド
lower-case letters:  文字クラスと角括弧式

M
Mixing g and number modifiers in the s command(sコマンドのgやnumberフラグの混在): The "s" Command
multiple files:  概要
multiple sed commands: sedスクリプト概要

N
n, and branching: 分岐とフロー制御
N, and branching: 分岐とフロー制御
named character classes(名前付き文字クラス):  文字クラスと角括弧式
newline, command separator: sedスクリプト概要
Next input line, append to pattern space: 他のコマンド
Next input line, replace pattern space with: 一般コマンド達
Non-bugs(それはバグじゃない), 0 address: バグ報告
Non-bugs(それはバグじゃない), in-place editing: バグ報告
Non-bugs(それはバグじゃない), localization-related: バグ報告
Non-bugs(それはバグじゃない), localization-related: バグ報告
Non-bugs(それはバグじゃない), N command on the last line: バグ報告
Non-bugs(それはバグじゃない), regex syntax clashes: バグ報告
numeric addresses:  アドレス概要
numeric characters:  文字クラスと角括弧式

O
omitting labels(ラベルの省略): 分岐とフロー制御
output(出力):  概要
output, suppressing(出力の抑制):  概要

P
p, example:  概要
paragraphs, processing(段落処理): 複数行テクニック
parameters, script:  概要
Parenthesized substrings(括弧で囲まれた部分文字列): The "s" Command
Pattern space, definition: 実行サイクル
Portability, comments(コメントの移植性): 一般コマンド達
Portability, line length limitations: 制限
Portability, N command on the last line: バグ報告
POSIXLY_CORRECT behavior, bracket expressions:  文字クラスと角括弧式
POSIXLY_CORRECT behavior, enabling:  コマンドラインオプション
POSIXLY_CORRECT behavior, escapes: エスケープ
POSIXLY_CORRECT behavior, N command: バグ報告
Print first line from pattern space: 他のコマンド
printable characters:  文字クラスと角括弧式
Printing file name: 拡張コマンド達
Printing line number: 他のコマンド
Printing text unambiguously: 他のコマンド
processing paragraphs(段落処理): 複数行テクニック
punctuation characters:  文字クラスと角括弧式

Q
Q, example:  終了ステータス
q, example: sedスクリプト概要
Quitting(sedの終了): 一般コマンド達
Quitting(sedの終了): 拡張コマンド達
quoted-printable lines, joining: 分岐とフロー制御

R
range addresses:  アドレス概要
range expression:  文字クラスと角括弧式
Range of lines:  範囲アドレス
Range with start address of zero:  範囲アドレス
Read next input line: 一般コマンド達
Read text from a file: 他のコマンド
Read text from a file: 拡張コマンド達
regex addresses and input lines: 正規表現アドレス
regex addresses and pattern space: 正規表現アドレス
regular expression addresses:  アドレス概要
regular expression, example: sedスクリプト概要
Replace hold space with copy of pattern space: 他のコマンド
Replace pattern space with copy of hold space: 他のコマンド
Replacing all text matching regexp in a line: The "s" Command
Replacing only nth match of regexp in a line: The "s" Command
Replacing selected lines with other text: 他のコマンド
Requiring GNU sed: 拡張コマンド達
restarting a cycle: 分岐とフロー制御

S
Sandbox mode:  コマンドラインオプション
script parameter:  概要
Script structure: sedスクリプト概要
Script, from a file:  コマンドラインオプション
Script, from command line:  コマンドラインオプション
sed commands syntax: sedスクリプト概要
sed commands, multiple: sedスクリプト概要
sed script structure: sedスクリプト概要
Selecting lines to process: 数値指定アドレス
Selecting non-matching lines:  アドレス概要
semicolons, command separator: sedスクリプト概要
Several lines, selecting:  範囲アドレス
Slash character, in regular expressions: 正規表現アドレス
space characters:  文字クラスと角括弧式
Spaces, pattern and hold: 実行サイクル
Special addressing forms:  範囲アドレス
standard input:  概要
Standard input, processing as input:  コマンドラインオプション
standard output:  概要
stdin:  概要
stdout:  概要
Stream editor: はじめに
subexpression:  後方参照と部分式
Subprocesses: The "s" Command
Subprocesses: 拡張コマンド達
Substitution of text, options: The "s" Command
suppressing output:  概要
syntax, addresses: sedスクリプト概要
syntax, sed commands: sedスクリプト概要

T
t, joining lines with: 分岐とフロー制御
t, versus b(t V.S. b): 分岐とフロー制御
Text, appending: 他のコマンド
Text, deleting: 一般コマンド達
Text, insertion: 他のコマンド
Text, printing: 一般コマンド達
Text, printing after substitution: The "s" Command
Text, writing to a file after substitution: The "s" Command
Transliteration: 他のコマンド

U
Unbuffered I/O, choosing:  コマンドラインオプション
upper-case letters:  文字クラスと角括弧式
Usage summary, printing:  コマンドラインオプション

V
Version, printing:  コマンドラインオプション

W
whitespace characters:  文字クラスと角括弧式
Working on separate files:  コマンドラインオプション
Write first line to a file: 拡張コマンド達
Write to a file: 他のコマンド

X
xdigit class:  文字クラスと角括弧式

Z
Zero, as range start address:  範囲アドレス

Jump to:   -   0   ;  
A   B   C   D   E   F   G   H   I   J   L   M   N   O   P   Q   R   S   T   U   V   W   X   Z  

sedコマンドとそのオプションの索引

全てのsed コマンドとコマンドラインオプションのアルファベット順リストです。

Jump to:   #   -   :   =   {  
A   B   C   D   E   F   G   H   I   L   N   P   Q   R   S   T   U   V   W   X   Y   Z  
索引見出し  掲載節

#
# (コメント): 一般コマンド達

-
--binary:  コマンドラインオプション
--debug:  コマンドラインオプション
--expression:  コマンドラインオプション
--file:  コマンドラインオプション
--follow-symlinks:  コマンドラインオプション
--help:  コマンドラインオプション
--in-place:  コマンドラインオプション
--line-length:  コマンドラインオプション
--null-data:  コマンドラインオプション
--posix:  コマンドラインオプション
--quiet:  コマンドラインオプション
--regexp-extended:  コマンドラインオプション
--sandbox:  コマンドラインオプション
--separate:  コマンドラインオプション
--silent:  コマンドラインオプション
--unbuffered:  コマンドラインオプション
--version:  コマンドラインオプション
--zero-terminated:  コマンドラインオプション
-b:  コマンドラインオプション
-e:  コマンドラインオプション
-E:  コマンドラインオプション
-f:  コマンドラインオプション
-i:  コマンドラインオプション
-l:  コマンドラインオプション
-n:  コマンドラインオプション
-n, スクリプト内で強制する 一般コマンド達
-r:  コマンドラインオプション
-s:  コマンドラインオプション
-u:  コマンドラインオプション
-z:  コマンドラインオプション

:
: (label) ラベルコマンド: プログラミングコマンド

=
= 行番号プリントコマンド: 他のコマンド

{
{} コマンドグループ化: 一般コマンド達

A
a (append text lines;テキスト行追加)コマンド: 他のコマンド
alnum 文字クラス:  文字クラスと角括弧式
alpha 文字クラス:  文字クラスと角括弧式

B
b (branch;分岐)コマンド: プログラミングコマンド
blank 文字クラス:  文字クラスと角括弧式

C
c (change to text lines;テキスト行変更)コマンド: 他のコマンド
cntrl 文字クラス:  文字クラスと角括弧式

D
D (delete first line;最初の行を削除)コマンド: 他のコマンド
d (delete)コマンド: 一般コマンド達
digit 文字クラス:  文字クラスと角括弧式

E
e (evaluate;eval)コマンド: 拡張コマンド達

F
F (File name)コマンド: 拡張コマンド達

G
G (appending Get)コマンド: 他のコマンド
g (get)コマンド: 他のコマンド
graph 文字クラス:  文字クラスと角括弧式

H
H (append Hold)コマンド: 他のコマンド
h (hold)コマンド: 他のコマンド

I
i (insert text lines)コマンド: 他のコマンド

L
l (list unambiguously;非表示文字も目に見えるようにリストする)コマンド: 他のコマンド
lower 文字クラス:  文字クラスと角括弧式

N
N (append Next line)コマンド: 他のコマンド
n (next-line)コマンド: 一般コマンド達

P
P (print first line)コマンド: 他のコマンド
p (print)コマンド: 一般コマンド達
print 文字クラス:  文字クラスと角括弧式
punct 文字クラス:  文字クラスと角括弧式

Q
q (quit;終了)コマンド: 一般コマンド達
Q (silent Quit)コマンド: 拡張コマンド達

R
r (read file)コマンド: 他のコマンド
R (read line)コマンド: 拡張コマンド達

S
s コマンド、オプションフラグ: The "s" Command
space 文字クラス:  文字クラスと角括弧式

T
T (test が失敗したら分岐する)コマンド: 拡張コマンド達
t (test が成功したら分岐する)コマンド: プログラミングコマンド

U
upper 文字クラス:  文字クラスと角括弧式

V
v (version)コマンド: 拡張コマンド達

W
w (write file)コマンド: 他のコマンド
W (write first line)コマンド: 拡張コマンド達

X
x (eXchange)コマンド: 他のコマンド
xdigit 文字クラス:  文字クラスと角括弧式

Y
y (変換)コマンド: 他のコマンド

Z
z (Zap)コマンド: 拡張コマンド達

Jump to:   #   -   :   =   {  
A   B   C   D   E   F   G   H   I   L   N   P   Q   R   S   T   U   V   W   X   Y   Z  

目次


脚注

(1)

これは'='、'a'、'c'、'i'、'l'、'p'のようなコマンドにも適用されます。. それでも、'w'、'W'コマンドに /dev/stdout を指定して標準出力に書き込む事ができます。

(2)

注意:GNU sedは実際に変更が行われたかどうかにかかわらずバックアップファイルを作成します。

(3)

'-i'オプションが指定されてない限り、これは'p'と同じです。

(4)

'-i'オプションが指定されてない限り、これは'p'と同じです。

(5)

もちろん、同じ事をするのにいろんな方法があります。例えば次のようなのです。

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

(6)

ここで紹介しているエスケープは、\n を除きGNU拡張です。基本正規表現モードでは、環境変数 POSIXLY_CORRECT をセットするとブラケット('['...']')の中でそれを無効にします。

(7)

正規表現のマルチバイト文字処理についてはオペレーティングシステムとlibcの実装に依存するものがあります。ここで挙げた例はglibcを使うGNU/Linuxシステムでは期待どおりに動く事が分かっています。

(8)

実際には、sedが行末の改行無しの行をプリントするときでも、同じ出力ストリームに更にテキストが送られると、行末の改行なしの行に続いて改行をプリントしてから更なるテキストをプリントします。単に内容の通り出力するのではないわけで、sed -n pコマンドはcatコマンドと完全に同じ動作ではありません。

(9)

sed導師のGreg UbbenはRPNdcを実装しました!それはsedと一緒に配布されました。

(10)

これにはバナー出力を埋め込むためのもう一つのスクリプトが必要です。例えば次のようなのです。

#!/bin/sh

banner -w $1 $2 $3 $4 |
  sed -e :a -e '/^.\{0,'$1'\}$/ { s/$/ /; ba; }' |
  ~/sedscripts/reverseline.sed

(11)

いくつかのsed実装では1スクリプト辺りのコマンド数は199までという制限があります。

(12)

これは、動作の変更を促した実際の「バグ」です。