[ << ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
sed
プログラムは,一つ以上のsed
コマンド,一つ以上の
`-e',`-f',`--expression',そして`--file'オプション,
またはこれらのオプションが使用されていない場合は最初のオプションではない
引数で渡されるものから成り立っています.このドキュメントは"その"
sed
スクリプトを記述します.渡されるscriptと
script-fileを全て連結したものの意味はこれで理解できるでしょう.
それぞれのsed
コマンドは,オプションのアドレスやアドレスの範囲から
成り立っていて,それには一文字のコマンド名と追加のコマンド特有のコードが
続きます.
3.1 sed で行を選択する | Selecting lines with sed | |
3.2 正規表現の構文の概要 | Overview of regular expression syntax | |
3.3 sed がデータをバッファリングする場所 | Where sed buffers data | |
3.4 よく使用されるコマンド | Often used commands | |
3.5 s コマンド | sed 's Swiss Army Knife | |
3.6 あまり使用されないコマンド | Less frequently used commands | |
3.7 sed のベテランプログラマのためのコマンド | Commands for sed gurus | |
3.8 GNU sed 特有のコマンド | Commands specific of GNU sed | |
3.9 正規表現でのエスケープに関するGNUの拡張 | Specifying special characters |
sed
で行を選択する
sed
スクリプトのアドレスは,以下の形式のどれでも可能です.
sed
は,-i
や-s
オプションが指定されていない限り,全ての入力行に渡り,連続し
て行を数えることに注意してください.)
1~2
を使用することになるでしょう.二行目から始
まり三行ごとに取り上げるため,2~3
を使用することになるでしょう.十
行目から始まり五行ごとに取り上げるため,10~5
を使用することになる
でしょう.そして,50~0
は50
告げる曖昧な方法にすぎません.
-i
や-s
オプションが与えられているときは,それぞれのファイルの最後の行にマッチし
ます.
/
文字が含まれる場合,それぞれバックスラッシュ(\
)でエスケー
プする必要があります.
POSIXLY_CORRECT
が設定されていない場合,空の正規表現//
は,
前回の正規表現に繰り返しマッチします(それは,空の正規表現がs
コマ
ンドに渡されても同じです).正規表現を編集すると,正規表現がコンパイルさ
れるときに評価されるので,空の正規表現とともにそれらを指定することは不正
な処理になることに注意してください.代わりにPOSIXLY_CORRECT
が設定
されている場合,//
は何にもマッチしません.この動作はPOSIXか
ら依頼されていますが,GNU sed
のデフォルトの動作を軽率に変更すると,
かなり多くの古いsedスクリプトが駄目になるでしょう.
%
はその他全ての単一の文字で置換してもかまいません.)
これは正規表現regexpにもマッチしますが,これで/
以外の分離文
字を使用することが可能になります.regexp自身が大量の/
を含ん
でいる場合,個々の/
をエスケープするのも退屈なので,それを避けると
き特に役に立ちます.regexp自身が分離文字を含んでいる場合,それぞれ
をバックスラッシュ(\
)でエスケープする必要があります.
I
指示語はGNUの拡張で,それにより
regexpは大文字小文字を無視してマッチします.
M
指示語は,GNU sed
の拡張で,^
と$
を(通常の動作に加え)それぞれ改行後の空の文字列と改行前の空の文
字列にマッチさせます.バッファの最初とバッファの最後に常にマッチする特別
な文字の並び(Perlモードの\A
と\Z
,基本または拡張正規表現モー
ドの\`
と\'
)があります.M
はmulti-lineを意味し
ます.
アドレスが与えられていない場合,全ての行がマッチします.一つのアドレスが 与えられている場合,マッチする行はアドレスがマッチしたものだけになります.
アドレスの範囲はカンマ(,
)で分けられている二つのアドレスで指定する
ことで指定することが可能です.アドレスの範囲は最初のアドレスにマッチして
いる行から始まり,二番目のアドレス(これは含まれます)にマッチするまで続き
ます.二番目のアドレスが正規表現の場合,マッチの終りの調査は,最初のアド
レスにマッチした行の次の行から開始されます.GNUの拡張として,
regexpが最初の入力行にもマッチするように,0
の行番号を
0,/regexp/
のようなアドレス指定で使用することが可能です.
二番目のアドレスがnumberで最初にマッチした行のアドレスより小さい (または同じ)場合,一行のみマッチします.
GNU sed
も特殊な二つのアドレス形式をサポートしています.
アドレス指定の終りに!
文字を後置するとマッチの意味が否定されます.
すなわち,!
がアドレスの範囲に続いている場合,選択されたアドレスの
範囲にマッチしない行だけが選択されます.これは一つのアドレスに対
しても動作し,おそらくひねくれているだけでしょうが,何もないアドレスに対
しても動作します.
sed
の使用方法を知るため,正規表現(短くするとregexp)を理解す
べきです.正規表現とは,右から左へならぶ対象文字列に対してマッチするパター
ンです.パターン内のほとんどの文字はその文字自身を意味し,対象内の対応す
る文字にマッチします.ちょっとした例として以下のパターンを考えます.
The quick brown fox |
それは,それと全く同一なサブジェクトの文字列の一部にマッチします.正規表
現のパワーは,パターン内に代入と繰り返しを含めるという能力にあります.そ
れらはメタ文字を使用してパターン内にエンコードされ,その文字自身を意味せ
ず,特殊な方法で解釈されます.sed
で使用される正規表現の構文の短い
記述は以下のようになります.
char
*
\+
\?
\{i\}
\{i,j\}
\{i,\}
\(regexp\)
\(abcd\)*
のような,後置されるオペレータを適用します.これは,ゼロ
以上の`abcd'全体の連続を検索しますが,abcd*
は`abc'にゼ
ロ以上の`d'が続くものを検索します.
.
^
^#include
は,"#include"が行の最初にあるとこ
ろだけにマッチします -- その前に一つか二つのスペースがある場合,マッチ
は失敗します.
$
^
と同じですが,行の終りを参照します.
[list]
[^list]
キャレットは正規表現の意味を反転し,リスト以外の単一文字にマッチします. リストに`]'を含めるため,それを(必要なキャレットの後の)最初の文字に し,`-'をリストに含めるため,それを最初または最後にしてください. `^'を含めるため,最初の文字より後に書いてください.
regexp1\|regexp2
\digit
\(\)
で参照しているものにマッチします.
\char
\n
だけだということに注意してくださ
い.特に\t
は,ほとんどのsed
実装でタブ文字ではなく`t'
にマッチします.
正規表現のマッチは欲張り,つまり二つ以上のマッチが検出された場合は最も長 いものを選択し,二つ以上同じサイズのものを選択した場合はテキストの最初の ものを選択することに注意してください.
例です.
sed
がデータをバッファリングする場所
sed
は二つのデータバッファを管理します,アクティブなパターン
スペースと,補助的なホールドスペースです."通常の"処理では,
sed
は入力ストリームから一行読み込み,それをパターンスペースに配置
します.このパターンスペースとは,テキストの操作を行なう場所です.ホール
ドスペースは最初は空ですが,パターンスペースからホールドスペース間でデー
タを移動するコマンドがあります.
本当にsed
を使用するのなら,きっとこれらのコマンドを知りたいと思う
でしょう.
#
"コマンド"はコメントを開始します.コメントは次の改行まで続きま
す.
移植性を心配している場合,sed
(POSIX.2に準拠していないもの)の
実装によっては,単一の一行のコメントのみサポートしていて,スクリプトの最
初の文字が#
のときだけサポートしている可能性があることを覚えておい
てください.
警告:sed
スクリプトの最初の二文字が#n
の場合,`-n'(自
動的に出力しない)オプションが強制的に使用されます.スクリプトの最初の行
にコメントを書き,そしてコメントを文字`n'で開始したい場合で,このように
動作して欲しくない場合は,大文字の`N'を使用するか,`n'の前に少なくとも一
つのスペースを書いてください.
それ以上のコマンドも入力も処理せずsed
を終了します.自動的な出力が
-n
スイッチで利用不可能になっていない場合,現在のパターンスペース
が出力されることに注意してください.sed
スクリプトがからの終了コー
ドを返す能力は,GNU sed
の拡張です.
-n
コマンドラインオプションと組み合わせて使用します.
注意:このようなsed
の実装では,自動的な出力が利用不可能ではなく
p
が与えられているとき,出力行が二重になるものもあります.それ以外
の実装では,行は一回だけ出力されます.両方ともPOSIX.2の標準に準拠し
ていて,どちらかをエラーと考えることはできません.
このため,移植性の高いsed
スクリプトでは,どちらかの動作に依存する
ことは避けるべきです.`-n'を使用して出力したいものを明示的にするか,
p
コマンド(とs
コマンドのp
フラグ)の使用を避けてくださ
い.
sed
はそれ以上のコマンドを処理せずに終了します.
{
文字と}
文字で囲んでもかまいません.
コマンドのグループを,単一のアドレス(またはアドレスの範囲)にマッチしたこ
とで開始したいとき,これは特に役に立ちます.
s
コマンド
(置換での)s
コマンドの構文は,
s/regexp/replacement/flagsです./
文字は,他の単
一文字をs
コマンドで与えることで一様に置換してもかまいません.
/
文字(または,それの代わりの使用されているその他の文字)は,
\
文字を前置した場合だけregexpやreplacementに書くこと
が可能です.
s
コマンドは,おそらくsed
で最も重要で,様々なオプションが多
くあります.基本的な概念は単純です.s
コマンドは,提供されている
regexpに対しパターンスペースのマッチを試みます.マッチが成功する場
合.マッチしたパターンスペースの位置がreplacementで置換されます.
replacementに\n
(nは1から9までの数字で,1と9も含
まれます)での参照を含めることが可能で,それはn番目の\(
とそ
のマッチと\)
に含まれているマッチの位置を参照します.また,
replacementに,パターンスペースのマッチ位置全体を参照する,エスケー
プされていない&
文字を含めることも可能です.
最終的に(これはGNU sed
の拡張です),特別なバックスラッシュの並びや文
字LlUuE
の一つを含めることが可能です.それぞれの意味は以下のとおり
です.\U
や\E
が見つかるまで小文字に置換します.次の文字を小
文字に置換します.\L
や\E
が見つかるまで大文字に置換します.
次の文字を大文字に置換します.そして,\L
や\U
で開始した大文
字小文字の変換を停止します.\
,&
,または改行そのものを最終
的な置換物に含めるため,replacement内の\
,&
,または
改行に必要な\
を確実に前置してください.
s
コマンドにはゼロ以上の以下のflagsを続けることが可能です.
注意:POSIX.2の標準は,g
とnumber指示語を混ぜたときに何
が起こるかを指定しておらず,現在はsed
の実装上で幅広い同意はありま
せん.GNU sed
では,相互作用は以下のように定義しています.
number番目のマッチを無視し,number番目からマッチし,すべての
マッチを置換します.
注意:p
とe
オプションの両方が指定されているとき,二つの順序
に関連して,全く違った結果を生成します.一般的にep
(評価して出力)
では期待したものになるでしょうが,もう一方の順番はデバッグで役に立つもの
になります.この理由は,現在のバージョンのGNU sed
が,e
前後の
p
オプションの存在を特別なものとして解釈しますが,s
コマンド
に対する一般的なフラグはその効果を一度だけ表示するためです.この動作は,
ドキュメントには書かれていますが,将来のバージョンでは変更するかもしれま
せん.
sed
の拡張として,file-nameの特殊な値をサポートします.結
果を標準エラー出力に書き出す`/dev/stderr',そして標準出力に書き出す
`/dev/stdout'です.(3)
nul
文字が含まれる場合,
結果は定義されていません.これはGNU sed
の拡張です.
I
修飾子はGNUの拡張で,大文字小文字を無
視する方法で,sed
にregexpにマッチさせます.
M
指示語は,GNU sed
の拡張で,^
と$
を(通常の動作に加え),それぞれ改行後の空の文字列と改行前の空の
文字列にマッチさせます.バッファの最初とバッファの最後に常にマッチする特
別な文字の並び(Perlモードの\A
と\Z
,基本または拡張正規表現
モードの\`
と\'
)があります.M
はmulti-lineを意
味します.
前のセクションのものより使用されることはおそらく少ないでしょうが,非常に わずかな有用なSEDスクリプトには,以下のコマンドを組み込むことも可能 です.
sed
の拡張がサポートされていない場
合はsed
は異常終了し,それはその他のsed
の実装ではそれを実装
していないためです.
q
と同じですが,パターンスペースの内容を出力しません.
q
に似ていて,呼び出し側に終了コードを返す能力を提供しています.
この一見些細な機能を達成する唯一の別の方法は,-n
オプションを使用
する方法(スクリプトが不必要に複雑になります)や,見た目に影響しないように
ファイル全体を読み込むことで時間が無駄になるような以下の断片を利用する方
法なので,このコマンドは役に立ちます.
:eat $d # Quit silently on the last line N # Read another line, silently g # Overwrite pattern space each time to save memory b eat |
/
文字は,y
コマンドで与えられるその他の単一文字で一律に置
換してもかまいません.)
source-charsにマッチしたパターンスペースのすべての文字を,対応する dest-charsの文字に変換します.
/
(またはそのかわりに使用されている文字),\
,または改行のイ
ンスタンスは,それぞれのインスタンスに\
でエスケープを提供すること
でsource-charsやdest-charsのリストに書くことが可能です.
source-charsとdest-charsのリストには,(エスケープを取り除く
と)同じ数の文字を含める必要があります.
このコマンドに続いているテキストの行(最後が\
で終っているものは,
出力から取り除かれます)を,現在のサイクルの終りや,次の入力行が読み込ま
れたときに出力されるキューに保存します.
GNUの拡張として,a
と改行の間に空白と\
の連続がある場合,
a
の後の最初の空白文字以外で始まるこの行のテキストは,textブ
ロックの最初の行として受けとられます.(これで,単純に一行のスクリプトを
追加するだけで可能になります.)この拡張は,i
とc
コマンドを
用いても動作します.
このコマンドに続いている行(最後が\
で終っているものは,出力から取
り除かれます)をすぐに出力します.
\
で終っているものは,出力から取り除かれます)を,最後の行
の位置(または,アドレスが指定されていない場合はそれぞれの行の位置)に出力
します.新しいサイクルは,パターンスペースが削除されてから,このコマンド
終了後に開始されます.
\
文
字)は,Cの形式でエスケープされた様式で出力されます.長い行は分割を示す
\
を後置して分割されます.それぞれの行の終りには$
で印が付き
ます.
nは,要求される行を丸める長さを指定します.0(ゼロ)の長さは長い行を
丸めないことを意味します.省略されている場合,コマンドラインで指定されて
いるものがデフォルトとして使用されます.nパラメータはGNU sed
の拡張です.
sed
の拡張は,fmt
が行なうように,(最大)n文字の
行の出力を生成するため,パターンスペースの行を補充しつなげます.n
が省略されている場合,コマンドラインで指定されているデフォルトを使用しま
す.
ブランク行,単語の間のスペース,そして字下げは出力で維持されます.異なる 字下げが連続している入力行はつなげられません.タブは八列に展開されます.
パターンスペースに複数の行が含まれている場合,それらはつなげられますが,
パターンスペースは通常単一行を含んでいるので,単純なL;d
スクリプト
の動作はfmt -s
と同じです(すなわち,短い行を長い行の形式につなげま
せん).
nは,行を丸める長さを指定することを要求します.省略されている場合, コマンドラインで指定されているデフォルトを使用します.
filenameの内容を読み込み,,現在のサイクルの終りや次の入力行が読み 込まれたときに出力ストリームに挿入するためキューに保存します. filenameが読み込み不可能な場合,エラーを示すことなく空のファイルが 読み込まれているかのように扱われることに注意してください.
GNU sed
の拡張として,特殊な値`/dev/stdin'がファイル名としてサ
ポートされていて,それは標準入力の内容を読み込みます.
r
コマンド同様,特殊な値`/dev/stdin'がファイル名としてサポー
トされていて,それは標準入力の内容を読み込みます.
sed
の拡張として,
file-nameとして二つの特殊な値がサポートされています.
`/dev/stderr'は結果を標準エラー出力に書き出し,`/dev/stdout'は
標準出力に書き出します.(4)
最初の入力行が読み込まれる前に,ファイルは作成され(または切り詰められ)ま
す.同じfilenameを参照するすべてのw
コマンドは(s
コマ
ンド成功時のw
フラグのインスタンスを含めて),ファイルを閉じ再び開
くこと無く出力されます.
sed
は終了しそれ以上のコマンドを処理し
ません.
sed
のベテランプログラマのためのコマンド
ほとんどの状況で,これらのコマンドを使用するよりは,おそらくawk
や
Perlのようなものでプログラムをした方が良いでしょう.しかし,時には
sed
に執念を燃やす人もいて,これらのコマンドで全く複雑なスクリプト
を書くことも可能になります.
条件分岐コマンドに対するlabelの位置を指定します.それ以外では何も しません.
s
の置換で成功し
たしたものがある場合のみlabelに分岐します.labelは省略可能で,
その場合は次のサイクルが開始されます.
s
の置換で成功し
なかったものがある場合のみlabelに分岐します.labelは省略可能
で,その場合は次のサイクルが開始されます.
sed
特有のコマンド
以下のコマンドはGNU sed
特有なので,注意して使用する必要があり,移植
性の邪魔になると分かっているときだけ使用することはそう悪いものではありま
せん.それらでGNU sed
の拡張を調査したり,標準的なsed
ではまだ
サポートされていないが,よく要求される作業を行なうことが可能になります.
v
sed
の拡張がサポートされていない場
合はsed
は異常終了し,それはその他のsed
の実装ではそれを実装
していないためです.
Q [exit-code]
q
と同じですが,パターンスペースの内容を出力しません.
q
に似ていて,呼び出し側に終了コードを返す能力を提供しています.
この一見些細な機能を達成する唯一の別の方法は,-n
オプションを使用
する方法(スクリプトが不必要に複雑になります)や,見た目に影響しないように
ファイル全体を読み込むと時間が無駄になるような以下の断片を利用する方法な
ので,役に立つはずです.
:eat $d # Quit silently on the last line N # Read another line, silently g # Overwrite pattern space each time to save memory b eat |
T label
s
の置換で成功し
なかったものがある場合のみlabelに分岐します.labelは省略可能
で,その場合は次のサイクルが開始されます.
e [command]
e
コマンドは
パターンスペースで見つかったコマンドを実行し,パターンスペースを出力で置
換します.後置される改行は抑制されます.
パラメータが指定されている場合は,代わりにe
コマンドがそれをコマン
ドとして解釈し,(r
が行なうように)それを出力ストリームに送ります.
そのコマンドは,最後の終りがバックスラッシュでない限り,複数の行を跨って
実行することが可能です.
いずれの場合でも,実行されたコマンドにnul
文字が含まれる場合,結果
は定義されていません.
W filename
w
コマンドですべて述べています.
L n
sed
の拡張は,fmt
が行なうように,(最大)n文字の
行の出力を生成するため,パターンスペースの行を補充しつなげます.n
が省略されている場合,コマンドラインで指定されているデフォルトを使用しま
す.
ブランク行,単語の間のスペース,そして字下げは出力で維持されます.異なる 字下げが連続している入力行はつなげられません.タブは八列に展開されます.
パターンスペースに複数の行が含まれている場合,それらはつなげられますが,
パターンスペースは通常単一行を含んでいるので,単純なL;d
スクリプト
の動作はfmt -s
と同じです(すなわち,短い行を長い行の形式につなげま
せん).
nは,行を丸める長さの指定を要求します.省略されている場合,コマン ドラインで指定されているデフォルトを使用します.
R filename
r
コマンド同様,特殊な値`/dev/stdin'がファイル名としてサポー
トされていて,それは標準入力の内容を読み込みます.
この章まで,sed
にキャレットを特殊文字でなく文字通りに解釈するよう
に伝える`\^'の形式のエスケープだけを見てきました.例えば,`\*'
はゼロ以上のバックスラッシュでは無く単一のアスタリスクにマッチします.
この章では,他の種類のエスケープを紹介します(5) -- すなわち,通常の文字や文字の連続に適用されるエスケー
プは文字通りに受けとられ,sed
は特殊文字で置換します.これは,パター
ンスペースの印刷不可能な文字を目に見える方法でエンコードする方法を提供し
ます.sed
スクリプト内での印刷不可能な文字の存在に制限はありません
が,スクリプトがシェルやテキストの編集で準備されるとき,バイナリ文字で表
現するより,以下のエスケープシーケンスの一つを使用する方が通常は簡単です.
これらのエスケープのリストは以下にあります.
`\b'(バックスラッシュ)は,既存の"単語の境界"の意味と衝突するので削 除されています.
それ以外のエスケープは特定の文字集合にマッチし,正規表現内だけで有効です.
[ << ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |