---------- SED 教室 第三回 「スクリプト」 ---------- 前回スクリプトの文法をちょっと紹介しましたが、復習を兼ねてもう一度今度 はもっと詳しく説明したいと思います。再び head -5 の真似をする SED スクリ プトです。 <<< HEAD.SED >>> --------------------------------------- 5q p d --------------------------------------- このスクリプトの使い方は sed -f HEAD.SED とするんでしたね。もちろん -e オプションを使ってコマンドラインに書くこともできますが、こっちの方が見や すいので以後スクリプトファイルのみを書くことにします。スクリプトファイル には一行に一つづつ命令を書きます。 え?昨日は sed -e 5q と書いたのに、今日は 2 行よけいな物がついているっ て? もうちょっとしたら説明しますので今の所はこのスクリプトファイルでも 標準入力の最初の 5 行が標準出力にでてくる事を確認して、ああ同じ動作をす るスクリプトだな、と納得しておいてください。 まず HEAD.SED で使われている命令から説明しましょう。 p パターンスペースの内容と改行コードを続けて標準出力に吐き出します。 print の p と覚えておきましょう。 パターンスペースは SED が標準入力から読み込んできた一行分の文字列 を入れておく場所です。スペースなどというと何物かと思ってしまいます が、単なる文字列の記憶場所です。 q パターンスペースの内容と改行コードを続けて標準出力に吐き出した後 実行終了。昨日も説明しましたね。quit の q です。 d パターンスペースの内容を削除し、標準入力から次の行をパターンスペー スに読み込む。そしてスクリプトの先頭へジャンプ。delete の d でしょう。 これだけでは何の事やら良くわからないと思うので、SED の実行を順を追って 説明しましょう。標準入力から次のファイルを読み込む事にします。 <<< INPUT.TXT >>> --------------------------------------- これは一行目だ。 こっちは二行目。 そして三行目。 つづいて四行目。 これが五行目。 六行目。 最後の七行目。 --------------------------------------- 実行は sed -f HEAD.SED < INPUT.TXT でしたね。 実は sed -f HEAD.SED INPUT.TXT とする事もできるのです。入力ファ イルが複数ある時は sed -f HEAD.SED INPUT1.TXT INPUT2.TXT などとします。 この場合は INPUT1.TXT と INPUT2.TXT の二つのテキストをつなげたものが入力 となります。 SED は起動されるとまず、標準入力の最初の行をパターンスペースにコピーし ます。この時点でパターンスペースの内容は「これは一行目だ。」になります。 行末の改行コードは捨てられてパターンスペースの中にはありませんので注意し てください。そして SED はおもむろにスクリプトの一行目を見ます。「5q」で す。5 は標準入力から読み込んだテキストの「5 行目ならば」という条件でした ね。現在読み込んでいるのは 1 行目なので残念ながら条件は成立しませんので 続く命令「q」は実行しません。 次に SED はスクリプトの二行目を見ます。「p」。おっとこの行には条件があ りません。この様な行は無条件に実行します。したがってパターンスペースの内 容と改行コードを続けて標準出力に吐き出します。標準出力は次のようになるで しょう。 --------------------------------------- これは一行目だ。<改行> --------------------------------------- 何の事はない、結果としては標準入力の 1 行目がそのまま出てきただけです。 そして SED はスクリプトの三行目を見ます。「d」。この行も条件がありませ んから無条件実行です。えーと、まずパターンスペースの内容を削除し、標準入 力の次の行を読み込む。この時点でパターンスペースの内容は「こっちは二行目。」 になりました。そしてスクリプトの先頭へジャンプ。 次に SED が見るのは大方の予想通りスクリプトの一行目です。つまり SED は 「ジャンプせよ」という命令を実行しない限り、スクリプトを一行目から順に条 件が成立する行だけ実行し、「ジャンプせよ」という命令 (この場合は d です ね) を実行すると次はジャンプの行き先の行 (この場合は一行目) から同様に見 て行くわけです。 では「ジャンプせよ」という命令を実行することなくスクリプトの最後の行を 過ぎてしまったらどうなるのでしょうか。むなしいですね。ボーナスがいつ出る か、いつ出るかと期待していたら年が明けてしまったようなものです。(えっ、 ボーナスって決まった日に出るのですかそりゃまたどうも失礼しました。) この 様な場合、SED は p と d を自動的に実行します。ということはつまり、スクリ プトの最後の二行が p と d ならばその二行を削除しても同じ動作をするという 事です。ですから HEAD.SED は次のようにしても同じ動作をします。 --------------------------------------- 5q --------------------------------------- さてスクリプトの一行目は「5q」。条件が 成立しませんので何もしません。 次にスクリプトの二行目を見て「p」。標準出力は前回の出力と合わせて次の ようになります。 --------------------------------------- これは一行目だ。<改行> こっちは二行目。<改行> --------------------------------------- もう簡単ですね。標準入力の 5 行目を読むまでは同じ事の繰り返しですから 一気に飛ばしてスクリプトの三行目「d」で標準入力の 5 行目を読むところまで いっちゃいます。標準出力には既に --------------------------------------- これは一行目だ。<改行> こっちは二行目。<改行> そして三行目。<改行> つづいて四行目。<改行> --------------------------------------- が出力されました。現在のパターンスペースは「これが五行目。」です。スクリ プトの先頭にジャンプしまして、スクリプトの一行目を見ますと「5q」。現在読 み込んでいるのはずばり 5 行目ですから条件成立。「q」を実行します。 「q」はまずパターンスペースの内容と改行コードを続けて標準出力に吐き出 します。そして実行終了。結局標準出力に吐き出された内容は次にようになりま す。 --------------------------------------- これは一行目だ。<改行> こっちは二行目。<改行> そして三行目。<改行> つづいて四行目。<改行> これが五行目。<改行> --------------------------------------- お疲れさまでした。確かに標準入力の最初の 5 行が標準出力から出てきまし たね。 実は SED のスクリプトの基本はこれだけです。どうです、思ってたより簡単 でしょう。後は色々な「実行条件」と「命令」を一つづつ覚えて行けば良いので す。 命令「p」は、その時点でのパターンスペースを出力してくれるのですから、 SED の動きを詳しく調べたいときの絶好の道具になります。不可解な動作をする スクリプトの適当な場所に p を挿入してパターンスペースの内容を確認して行 くわけです。ものは試し、HEAD.SED の適当な行に p を挿入して動作を確認して みてください。 最後に新しい実行条件を二つほど紹介して終わりにしましょう。 $ 標準入力から現在読み込んでいる行が「最終行ならば」という条件。 「実行条件1」,「実行条件2」 実行条件1が成立した行から実行条件2が成立する行までの間の行。 たとえば 2,5 は「2 行目から 5 行目までの間ならば」という条件。 ではみなさん良い週末を。 --- GCD03723 (Greatest Common Divisor:最大公約数)