26.3.3 sed スクリプトの文法

前節 hwb26.3.2 sed の処理の流れ

sed "/Paul/!d" nobelprize.txtreturn2

というコマンドを実行しました.このスクリプトの /Paul/!d は /Paul/! と d の二つの部分に分かれ,

  1. /Paul/! は “Paul” を含まない行を意味します.該当行を読み込んだ後に,右側に書かれた一連のコマンドを実行します.
  2. d は,パターンスペース内のデータを削除するコマンドです.

このように sed スクリプトは「どの行で」「どの操作 (コマンド) を実行するか」という 2 つの項目を指定することで記述されます.行を指定する部分を「アドレス」と言います.アドレスとコマンドの記述の仕方を詳しく見てみましょう.

アドレスの記述

行番号による指定

sed スクリプトでは行を番号で指定することができます.たとえば “10p” というスクリプトは,10 行目で p コマンドを実行するという意味で,次のような動作をします.

sed -n "10p" nobelprize.txtreturn2
2002 Raymond Davis Jr., Masatoshi Koshiba, Riccardo Giacconi

また “3q” というスクリプトは 3 行目を読み込んだときに q コマンドを実行します.q コマンドは sed を終了させるという意味なので,sed “3q” は最初の 3 行のみを表示します.
sed "3q" nobelprize.txtreturn2
2011 Saul Perlmutter, Brian P. Schmidt, Adam G. Riess 2010 Andre Geim, Konstantin Novoselov 2009 Charles Kuen Kao, Willard S. Boyle, George E. Smith

ちなみに,これは head コマンドと同じ動作です.このように sed を使うことで head コマンドの肩代わりをさせることができます.
それから $ 記号でテキストファイルの最終行を表すことができます.たとえば次のようにすると,最後の 1  行だけが表示されます.
sed -n '$p' nobelprize.txtreturn2
1901 Wilhelm Conrad Röntgen

パターンマッチによる指定

行番号ではなく「…という文字列を含む行」という形式で行を指定することもできます.たとえば前節 hwb26.3.2 sed の処理の流れ で挙げた

sed -n "/Paul/p" nobelprize.txtreturn2

がパターンマッチによる行指定の例です.スラッシュ / を 2 個並べた間にパターンを書くことで,パターンにマッチする行のみにコマンドを実行することができます.このパターンの部分には単なる文字列ではなく,正規表現を書くことができます.また 2 個目のスラッシュの後ろに ! をつけると意味が反転し「マッチしない行」を表します.

行範囲による指定

アドレスをカンマ , で区切って 2 個並べると,その範囲の行全てに対してコマンドを実行させることができます.たとえば “11,15p” とすると,11 行目から 15 行目までに対して p コマンドを実行することができます.

sed -n "11,15p" nobelprize.txtreturn2
2001 Eric A. Cornell, Wolfgang Ketterle, Carl E. Wieman 2000 Zhores I. Alferov, Herbert Kroemer, Jack S. Kilby 1999 Gerardus 't Hooft, Martinus J.G. Veltman 1998 Robert B. Laughlin, Horst L. Störmer, Daniel C. Tsui 1997 Steven Chu, Claude Cohen-Tannoudji, William D. Phillips

行範囲を指定するには,行番号だけでなくパターンマッチで指定することもできます.ただパターンマッチで行を指定する場合,複数の行が一斉に指定されることがあります.予期せぬ挙動の原因になりますので,パターンマッチで指定する際は十分気をつけてください.

コマンドの記述

複数のスクリプトの指定

sed に実行させるスクリプトは同時に複数個指定することができます.たとえば次の例では Yukawa を含む行と Tomonaga を含む行を表示させています.

sed -n -e "/Yukawa/p" -e "/Tomonaga/p" nobelprize.txtreturn2
1965 Sin-Itiro Tomonaga, Julian Schwinger, Richard P. Feynman 1949 Hideki Yukawa

このように, sed に複数のスクリプトを与えるときは -e オプションを先頭につけてスクリプトを並べます.なお,スクリプトを複数指定した場合でも sed の動作する手順は代わりません.1 行を読み込んだら指定されたスクリプトを順番に実行し,全て実行し終わったら次の行を読み込みます.

ファイルからのスクリプト読み込み

-e オプションを使うと複数のスクリプトを並べることができますが,この方法で 10 個も 20 個もスクリプトを並べるのは大変です.また,使い回しの効く便利なスクリプトは保存しておきたいものです.そういう場合のために,スクリプトをファイルから読み込むことができます.
スクリプトをファイルから読み込ませるには -f オプションに続けてファイル名を書きます.たとえば sample.sed に

/Yukawa/p
/Tomonaga/p

と書いておき,ターミナルで

sed -n -f sample.sed nobelprize.txtreturn2

と入力すると,上に書いた -e オプションの例と全く同じ結果を得ます.また一つの行アドレスに対して複数のコマンドを割り当てるには,中括弧を使います.たとえば sample2.sed に

10{
p
q
}

と書いておいて sed に読み込ませると,10 行目を読み込んだときにコマンド p と q を順番に実行します.したがって次のような出力になります.

sed -n -f "sample2.sed" nobelprize.txtreturn2
2002 Raymond Davis Jr., Masatoshi Koshiba, Riccardo Giacconi

このように複数のコマンドを組み合わせれば,sed でより色々な操作をすることができます.これまでに登場していないコマンドの紹介と合わせて,次節以降ではもっと高度な sed の使い方を説明します.