sed - テキストを置換や編集をする

sedコマンドのアドレスは行を何行かずつにして指定することができます。
wコマンドやrコマンドを用いれば、ファイルから内容を読み込んで、その内容を挿入したり、現在のパターンスペースをファイルに書き出すことができます。

コマンド例の想定

コマンドの例として、以下のような「apple」、「onion」、「yuzu」の重複順列でできたテキストファイルを想定します。

itemtext.txt ▼表示

また、sedコマンドのスクリプトが書かれたファイルをscript.sedとします。

アドレスについて(続き)

スクリプトは

で表現されます。
addr:行の位置や範囲を示すもので、行番号や正規表現を用いて指定できます。
X:sedコマンドの機能を決定する、一文字のことです。
options:Xで指定したものによって必要なオプションのことです。

ここでは、addr、つまりアドレスの指定方法についていくつか紹介します。

アドレスの範囲の終端を相対的に指定
(addr1,+num)

範囲の始点から次のnum行までを指定することができます。
コマンド例では、5行目から次の3行目、つまり8行目までを指定しています。

コマンド例

script.sed

itemtext.txt ▼表示

実行結果 ▼表示

アドレスをステップで指定
(first~step)

first行からstep行ずつを指定することができます。
コマンド例では、5行目から3行ずつ行を指定しています。

コマンド例

script.sed

itemtext.txt ▼表示

実行結果 ▼表示

範囲の終端を行数の倍数で指定
(addr1,~num)

範囲の始点からnum行の倍数までの行を指定します。
コマンド例では、5行目から4行目の倍数、つまりこの場合は8行目まで指定されます。

コマンド例

script.sed

itemtext.txt ▼表示

実行結果 ▼表示

アドレスで指定しなかったものを指定

アドレスの最後に「!」をつけることで、アドレスで指定したものとは逆、つまり、アドレスで指定しなかったものを指定することができます。

コマンド例

script.sed

itemtext.txt ▼表示

実行結果 ▼表示

アドレスで指定された行を別の文字列に置換
(cコマンド)

cコマンドは行を別の文字列に置換します。
アドレスが指定されていない場合はそれぞれの行について、文字列を置換します。

コマンド例

script.sed

itemtext.txt ▼表示

実行結果 ▼表示

範囲が指定されている場合は、それらの行を削除してから、文字列を置換します。

コマンド例

script.sed

実行結果 ▼表示

!を用いて、アドレスの範囲の逆を指定すると、アドレス指定がある範囲でcコマンドでアドレスを指定しなかった時と同じような動作になります。

コマンド例

script.sed

実行結果 ▼表示

cコマンドは実行された後にスクリプトがすぐに終了するため、その後にあるsedコマンドのスクリプトは実行されないことに注意しましょう。

現在の入力行の行番号を表示
(=コマンド)

=コマンドは、入力行の行番号を表示することができます。

コマンド例

script.sed

itemtext.txt ▼表示

実行結果 ▼表示

sedコマンドの-nオプションで余分な出力を除くと行番号のみを表示することができます。

コマンド例

script.sed

実行結果 ▼表示

アドレスで正規表現を使うと、その正規表現とマッチする行の行番号を表示することもできます。

例えば、行の終わりにappleの単語がある行の行番号を表示するとしたら、

コマンド例

script.sed

実行結果 ▼表示

のように表示させることができます。正規表現の$は行の終わりを示す記号になります。

パターンスペースを明確な形式で表示
(lコマンド)

lコマンドは、パターンスペースを明確な形式(unambiguous form)で表します。

ここで、明確な形式とは、

表示できない文字をC言語のエスケープ形式で示す。
長い行は\の文字で区切る。
それぞれの行の終端は$の記号で終了する。

というものになります。

コマンド例

script.sed

itemtext.txt ▼表示

実行結果 ▼表示

UTF-8の場合で、日本語は8進数形式で表示されます。

例えば、「あ」の場合だと「\343\201\202」のように表示されます。

コマンド例

実行結果

lコマンドの後に数字を入力するとその数字分の文字で行を折り返します。

コマンド例

script.sed

実行結果 ▼表示

パターンスペースの内容をファイルに出力
(wコマンド)

wコマンドは、パターンスペースの内容をファイルに書き出すことができます。
コマンド例では、itemtext.txtの3行目の内容を標準出力に出力します。

コマンド例

script.sed

itemtext.txt ▼表示

実行結果

/dev/stdoutを指定すると標準出力を指定することができます。
ほかにも、/dev/stderrを指定すると標準エラー出力を指定することができます。

ファイルから読み込んで内容を挿入
(rコマンド)

rコマンドは、指定したファイルの内容を次の行に挿入します。
コマンド例では、itemtext.txtの3行目の次の行にファイルの内容を挿入しています。

コマンド例

script.sed

text.txt

itemtext.txt ▼表示

実行結果 ▼表示

/dev/stdinを指定すると標準入力を指定することができます。

補足として、rコマンドはファイルの内容を次の行に対して挿入するが、工夫を行えば、手前に対して挿入しているかのように動作させることができます。

コマンド例

script.sed

実行結果 ▼表示

まず、初めのsedコマンドで最後の行にテキストを追記します。

このテキストの追加は、次のsedコマンドでパターンスペースとホールドスペースを入れ替えるxコマンドを使って、行をずらして出力させるためです。
行をずらして表示しますと最後の行が出力されません。
そのために最後の行に対して追加で何かテキストを追加します。

2つ目のsedコマンドを用いるとほとんど実行結果のように確認できます。
しかし、一番上の行に空行ができます。
これは最初のパターンスペースとホールドスペースの入れ替えにより、ホールドスペースの初期値が出力されるためです。
また、ホールドスペースの初期値は何もないため、一番上の行に空行が表示されます。

また、script.sedについて、「$q」を用いて、rコマンドで最後の行でファイルの内容を挿入させる前にsedコマンドのスクリプトを終了させます。
また、qコマンドはsedコマンドのスクリプトは終了させるコマンドです。

3つ目のsedコマンドで一番上にできた空行を削除します。そうすると上の実行結果のように出力されます。

また、script.sedの「$q」を削除して、3つ目のsedコマンドで出力の最後の行を削除しても、同様の実行結果ができます。

コマンド例