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
{、}、b、t、T、:の各コマンドはセミコロンで区切れます。これは移植性のないGNU sed拡張です。
$ seq 4 | sed '{1d;3d}'
2
4
$ seq 6 | sed '{1d;3d};5d'
2
4
6
b、t、T、:の各コマンドが使うラベルは、セミコロンまで読み込まれます。先頭と末尾の空白は無視されます。次の例のラベルは「x」です。最初の例はGNU sedで動作します。2番目は、それと同じ働きをする移植可能な書き方です。分岐とラベルの詳細は、分岐と制御の流れを参照してください。
$ 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 改行を必要とするコマンド
次のコマンドはセミコロンで区切れず、改行が必要です。
a、c、i(追加・変更・挿入)-
a、c、iの各コマンドの後にある文字は、すべて追加・変更・挿入するテキストとして扱われます。セミコロンを使うと、望ましくない結果になります。$ 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
追加するテキスト(「Hello」)を
a、c、iの直後に指定すること自体が、GNUsed拡張である点に注意してください。移植可能でPOSIXに準拠した別の書き方は、次のとおりです。$ seq 2 | sed '1a\ Hello 2d' 1 Hello
#(コメント)-
「#」の後から次の改行までの文字は、すべて無視されます。
$ 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(ファイルの読み書き)-
r、R、w、Wの各コマンドは、行末までをファイル名として読み取ります。空白、コメント、セミコロンがあれば、それらもファイル名に含まれ、予期しない結果につながります。$ 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
sedは、r、R、w、Wの各コマンドでの読み書きエラー(ファイルがない場合など)を、通知せずに無視することに注意してください。次の例では、sedは「hello.txt ; N」という名前のファイルを読もうとします。そのファイルはなく、エラーは通知されずに無視されます。$ 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](eまたはwフラグを使った置換)-
置換コマンドでは、
wフラグは置換結果をファイルへ書き込み、eフラグは置換結果をシェルコマンドとして実行します。r/R/w/W/eコマンドと同様に、これらは改行で終える必要があります。空白、コメント、セミコロンがあれば、それらもシェルコマンドやファイル名に含まれ、予期しない結果につながります。$ echo a | sed 's/a/b/w1.txt#foo' b $ ls -1 1.txt#foo