Look on the Bright Side of Things

Anderson's Blog - since 2005

Rubyでファイルの読み書き

ファイルからCSVデータを読んで、12列目までの項目毎になんか処理して別ファイルに書く

rfile = "c:\\readme.txt"
wfile = "c:\\writetoyou.txt"

rf = open(rfile)
# rf = open("c:\\readme.txt") でも可

wf = open(wfile,"w")
# w は新規作成モード

while line = rf.gets do
  arr = line.split(/,/)
  # カンマ区切りで配列生成

  i = 0

  arr.each do | cell |
  # 他言語でいうところの foreach
  # for文だと for cell in arr 

    if i <= 11
      cell.chomp!
      # 改行削除。メソッドに!マークを付けると、元配列を操作できる
      # これを破壊的メソッドというそうな

      cell = cell.gsub!(/[abc]/i,'E')
      # 要素中のabcをEに置換
    
      i += 1
      # i++のようなインクリメントは無い
	
    end
  end

  wf.puts(arr.join(","))
  #putsで改行付、printで改行無し
end

rf.close
wf.close

12列目までに対してchompしてるのは、7列目がリテラルなのだけれど、リテラル中にカンマや改行が含まれているため。末尾項目以外の改行は全てchompしちゃえばいいのだが、まぁ12列以上に改行が現れることは無いだろうと高を括っている。

簡単なプログラムだが、組んでみると色々と難儀した。
まず、Rubyならあると思ってた++や--などのインクリメント記法がなかった。VBで i = i + 1 とか書くのがダセェと感じてただけに、Rubyにもインクリメント記法がないのにちょっとガッカリ。
次にイテレータ。なんか好きでなかったので、もともとPerlでもforeachはあんまり使わず、for(i=0;i<$#arr;i++)を好んで使っていた。今回も同じ風にしてみたかったのだが、Rubyのforループはちょっと違う。よく解らなかったので上のようにしてみたが、あとでこう書き直せる事に気付いた。

  arr[0..11].each do | cell |
     cell.メソッド!
  end

これで配列の先頭12個に対してのみループする。これは便利。他にももっと単純な記法があるんだろうなー。
最初は破壊的メソッドについて知らなかったので、いちいち元配列に代入し直してたのだが、こっちの方が便利だ。
ちょっとPerlには戻れないかも知れない。時刻計算とかCPANに匹敵するモノがないのなら別だが。

んで、最終的な形は下。

rfile = "c:\\readme.txt"
wfile = "c:\\writetoyou.txt"

rf = open(rfile)
wf = open(wfile,"w")

while line = rf.gets do
  arr = line.split(/,/)

  arr[0..11].each do | cell |
      cell.chomp!
      cell = cell.gsub!(/[abc]/i,'E')
  end

  wf.puts(arr.join(","))
end

rf.close
wf.close