情報科学概論
2002.6.18

Back to index page


  1. 本日の作業内容

  2. 出席確認

    出席に関する注意事項を説明しますので,その注意を良く聞いてから,電子メールにより出席の申告をしてください.「件名」は

    gairon 6-18 attend s0240**

    のように自分の学生番号を使って下さい.なお,入力ミスがあると出席として認 められないことになりますので,慎重に行ってください.文 字はすべて1バイト文字 (半角英数字) です.途中に入るスペースは一度に一個だけと してください.スペースは全部で3個です.また,**の部分は自分の学生番号の下二桁 です.

  3. 正規表現 (その2)

    前回の授業では正規表現の基本的な使用法について概略を示すとともに,いくつ かの用例について説明しました.しかし,実際に使うとなると,具体的にどのよ うにすれば良いのか,分からないことも出てくるでしょう.今回は,さらに具体 的な例をいくつか挙げて,その動作について見てみることにしましょう.

    • HTMLソースファイルのタグ取り

      以前にHTMLの学習をしましたが,HTMLファイルの中身を見るとタグと本文が混在 していて,簡単には理解しづらいでしょう.ブラウザを使わないで,中身だけを 見たいときに,タグを取り去るスクリプトがあれば,役に立つかも知れません. 次の例はそのためのものです.まずは,HTMLの構造から復習してみましょう.

      1. タグの基本

        まず最初に挙げておくべきなのはタグは < > で囲まれているこ とです.すなわち,そのペアが出てくればタグであるので取り去る対象とします. しかし,/<.*>/ とすると,例えば,開始タグと終了タグの間に 英数字しかない場合には該当してしまうので,消去する範囲が多すぎます.

        
        #Wrong example for stripping HTML tags
        
        while line = gets
          print line.gsub(/<.*>/, " ")
        end
        

      2. 文字コード

        上の例を前回の宿題を紹介したページに対して実行してみましょう.エディタな どを利用して,前回の宿題のページのソースを task-jis.html として保存 します.XEmacsでは拡張子が .html のファイルを保存すると文字コー ドがJISコードというものに なってしまいます.Rubyできちんと日本語を扱うためには文字コードはEUCもし くはシフトJISでなければいけません.面倒ですが,漢字コード変換を行ってお きましょう.

        $ nkf -e task-jis.html > task.html

        これで,文字コードがEUCに変換されました.

      3. スクリプトの実行方法

        ここでは,Aクラスの宿題を対象として行ってみますが,スクリプトの 実行は以下のように行います.先ほど紹介したスクリプトを html.rb と言う名前で保存しておけば,ターミナルでの操作は次のようなものです.

        $ ruby html.rb < task.html

        リダイレクトの機能を利用して,RubyスクリプトにHTMLファイルを読ませていま す.結果はどうなるでしょうか.

         
         
         
         
         
        ディレクトリ内のファイル表示を行う コマンドはオプションによ
        り多様な表示形式を選択できる.ディレクトリ内のファイルを再帰的にlong形式
        で表
        示するためのオプションを コマンドにより調べ,それを利用し
        て次の条件を満たすスクリプトを作成せよ. 
         
         ファイル検索を行うトップディレクトリは自分のホームディレクトリとする.
             
         
         である
            ものを示す行のみを抽出する. 
         
        提出方法は以下の通りである. 
         
         としてメールに添付
            する. 
         としてメールに添付す
            る. 
         
         
         
         
         
         
         
         
         件名を間違えた場合は採点されないことがあるので注
        		     意すること 
         添付のファイル名を間違えた場合にはまったく採点さ
        		     れないので特に注意すること 
         質問用アドレス
        		       
         
         
         
         
         
         
         
         
        

      4. 不必要な改行の除去

        この例ではだいぶ中身が抜け落ちてしまいました.抜けている原因はいろいろあ りますが,とりあえず,XEmacsのyaHTMLモードが勝手に改行することがまず,問 題のようです.そこで,いったん改行を全部キャンセルしてからタグ取りしてみましょう.

        
        #Example for stripping newline character
        
        while line = gets
          print line.gsub(/\s/, "").gsub(/<.*>/, " ")
        end
        

        上の例では,改行だけでなく余分なインデントなども除去するために,空白文字 \s としています.すると,結果は,先ほどよりは少し良くなり,

        ディレクトリ内のファイル表示を行う コマンドはオプションにより多様な表示形式を選択できる.ディレクトリ内のファイルを再帰的にlong形式で表示するためのオプションを コマンドにより調べ,それを利用して次の条件を満たすスクリプトを作成せよ. ファイル検索を行うトップディレクトリは自分のホームディレクトリとする. であるものを示す行のみを抽出する. 提出方法は以下の通りである. としてメールに添付する. としてメールに添付する. 件名を間違えた場合は採点されないことがあるので注意すること 添付のファイル名を間違えた場合にはまったく採点されないので特に注意すること 質問用アドレス

        と言った具合いになるはずです.抜けているのは,ソース上の文章が英数字の部 分であることが分かります.

      5. 最長一致の解除

        正規表現は「最長一致」と言って,繰り返しパター ンをなるべく長くマッチさせるため,<tt> s0240**-6-11.rb </tt>の場合に,その部分全部とマッチさせてしまったのです.マッ チの条件を次のように変えてみましょう.

        
        #Example for stripping shortest pattern match
        
        while line = gets
          print line.gsub(/\s/, "").gsub(/<.*?>/, " ")
        end
        

        結果は各自で確認してください.

      6. 改行の再入力

        だいぶ見栄えが良くなったはずですが,最初に 必要な改行まで除去したため,1行になってしまっていて見通しが悪い構成で す.再び,改行を付与したいところですが,改行を加える部分をどこにするか が問題です.ここでは,HTMLタグの改行コマンドをそのまま使ってみましょう. タグを除去する前に <br> <p> </tr> と言った ソース上の改行コマンドを \n にあらかじめ置換しておきましょう.

        
        #Example for putting newline character again
        
        while line = gets
          print line.gsub(/\s/, "").gsub(/<p>|<br>|<\/tr>/,"\n").gsub(/<.*?>/, " ")
        end
        

      7. 最後の整形

        最後に途中の操作などで余分に入っている空白を除去しましょう.全部除去して しまうと文字が詰まって逆にみづらくなるので,空白文字が2つ以上続くものだ けを除去してみます.

        
        #Example for putting newline character again
        
        while line = gets
          print line.gsub(/\s/, "").gsub(/<p>|<br>|<\/tr>/,"\n").gsub(/<.*?>/, " "
        ).gsub(/\s{2,2}/,"")
        end
        

        最終的な状況は以下のようになるはずです.

         Task 2002-6-11   情報科学概論 Aクラス 宿題 2002.6.11ディレクトリ内のファイル表示を行うlsコマンドはオプションにより多様な表示形式を選択できる.ディレクトリ内のファイルを再帰的にlong形式で表示するためのオプションをjmanコマンドにより調べ,それを利用して次の条件を満たすスクリプトを作成せよ.
          ファイル検索を行うトップディレクトリは自分のホームディレクトリとする.
         スクリプトはどのディレクトリからでも使用可能とする.
         上述の条件を満たすオプションをつけたlsコマンドの出力結果からファイル名がcoreであるものを示す行のみを抽出する.
         提出方法は以下の通りである.
          スクリプトのファイル名をs0240**-6-11.rbとしてメールに添付する.
         スクリプトの実行結果を s0240**-6-11.txtとしてメールに添付する.
           提出先gaia@mag.shimane-u.ac.jp提出期限 2002.6.17 17:00
        件名ruby-a-6-11その他 学生番号と氏名を記載しておくこと
        Sylpheedを使用すること
        件名を間違えた場合は採点されないことがあるので注 意すること
        添付のファイル名を間違えた場合にはまったく採点さ れないので特に注意すること
        質問用アドレスagul@mag.shimane-u.ac.jp 
          Back 
        

        表の再現が難しいですが,とりあえずソースを見るのは楽になりました.このよ うに,必要なことを順に考えながら学習するのが効果的でしょう.なお, nkf を利用して一度中間的なファイル task.html を作成しましたが,そのようなファ イルを作らなくても,次のようにパイプを使って処理 することも可能です.

        $ nkf -e task-jis.html | ruby html.rb

    • ファイル名変換スクリプト

      ディレクトリにあるファイルの名前を一定の規則にしたがって変更する,という 要求は結構多くあります.ファイル名に日付を使用していたり,人名を使用して いた場合などそれを別の名前に変えたり,複製したりするためのスクリプトを考 えてみましょう.

      1. 基本的な考え方

        ls コマンドを実行して表示されるファイルの内,置き換えられるべき文字 列と置き換える文字列をコマンドライン引数から与えてやります.すなわち, ここでも gsub メソッドを利用することになります.また,スク リプト実行と同時にファイル名を変更してしまうのは,キーボード入力ミス があると意図しない変換になってしまうため,スクリプトはとりあえず動作 を確認するだけとし,実際には処理をシェルに引き渡す形とします.

      2. スクリプト例

        上の考え方に基づいて作成したスクリプトを以下に示します.

        
        #!/usr/bin/ruby
        
        oldname = `ls`
        namelist = oldname.split("\n")
        
        str_to_find = Regexp.new(ARGV[0])
        
        while line = namelist.shift
          print "mv ", line, " ", line.gsub(str_to_find,ARGV[1]), "\n" if line =~ ARGV[0]
        end
        

        スクリプト単独でも実行できるように冒頭に起動プログラム名を書いておきます. また,このスクリプトを例えば,filename.rb という名前で保存し たとすると,ターミナルで

        $ chmod +x filename.rb

        としておいて,実行権限を与えておきます.スクリプトには引数を与えるので, 例えば,カレントディレクトリに abc abcd abcdef という3つのファ イルがあるとすると,

        $ ./filename.rb ab xy

        というように使います.ただし,先ほども行ったように,それだけでは,

        
        mv abc xyc
        mv abcd xycd
        mv abcdef xycdef
        

        と表示されるだけで実際のファイル名の変更は行われません.動作を確認したら,

        $ ./filename.rb ab xy | sh

        というように,シェルに結果を引き渡すことにより実際にファイル名の変更が可 能です.引数を逆に使うとファイル名を元に戻せます.

      3. スクリプトの中身

        上記のスクリプトには新しいメソッドである new が使われています. 新たなオブジェクトを作成するメソッドですが,その前に Regexp と いうクラスを指定していますので,新しい正規表現オブジェクトを生成すること を行っています.コマンドライン引数から与えた文字列の正規表現パターンを自 分で考えなくても,自動生成してくれます.後は,ターミナルで動作する出力を print 文で作るだけですが,この部分の mv cp にすれば,複写になり ます.

  4. 実習作業

    様々な表現パターンを自分で工夫して探さないとなかなか身に付きません.空白 を名前に含むファイルを作ってしまった場合などこれを機会にファイル名を変更 するスクリプトを応用してディレクトリをすっきりさせましょう.

    ファイルを見つけるためのスクリプトは例えば,

    
    #!/usr/bin/ruby
    
    line = `ls -R ~ `
    name = line.split("\n")
    
    for i in 0...name.size
      print name[i], "\n" if /^\// =~ name[i]
      if /^\w*\s\w*/ =~ name[i]
        print  name[i], "\n"
      end
    end
    

    のようになるでしょう.これによりどのディレクトリにスペースを名前に含むファ イルがあるかが分かります.それが分かれば,そのディレクトリに移動してファ イル名変更のスクリプトを実行すれば良いのですが,上のファイル名変更スク リプトの応用で,以下のように書けます.

    
    #!/usr/bin/ruby
    
    oldname = `ls`
    namelist = oldname.split("\n")
    
    while line = namelist.shift
      print "mv \"", line, "\" ", line.gsub(/\s/,""), "\n" if line =~ /\s/
    end
    

    これも実際の処理はシェルに引き渡してから行う形式です.

  5. 宿題

    授業の終りに宿題 (AクラスBクラス別々) について説明しますので,アナウンスに注意してください.


ページトップに戻る

目次ページに戻る