Ruby ファイル処理 読込み・書込み スクリプトの書き方

バイオインフォ道場、くまぞうです。

ファイル操作ができるようになると、処理の幅が広がります。データの整形や集計などを簡単に済ませることができるようになります。基本は、「ファイルを開いて、1行ずつ処理をする。最後に閉じる」です。sedやawkを使っても同様のことが出来る場合が多いですが、より複雑な処理を行いたい場合には、プログラミング言語を使ったファイル処理の方法を検討すると良いと思います。尚、対象はテキストファイルのみとします。

スポンサーリンク



ファイル操作

手順

  1. ファイルを開く(読み込み・書き込みの指定)
  2. 1行ずつ処理を行う
  3. ファイルを閉じる

読み込み

ファイルをオープンしたときのデフォルトは読み出しモードです。ファイル操作として1行ずつ行う処理では、終端処理(chomp)や区切り処理(split)、表示(puts)などが良く使われます。また、条件に該当した行だけを処理する場合には、正規表現を使ったフィルタリングや、繰り返し制御に関する処理(next・breakなど)を使うことが多いです。

File.open("ファイル名").each do |line|
    line.split(/\t/)など 1行ずつ処理を行う(もしくは、入力レコード単位)
    ...
end

書き込み

ファイルを書き込む場合は、モードを”w”または”a”で指定します。”a”は末尾に追加する書き込み方式です。ログなどを書き込む場合はこのモードが便利です。ファイルをオープンした識別子(例ではf)に対してputs・printfなどの出力操作を行うことで、ファイルに書き込みが行われます。

File.open("ファイル名","w") do |f|
    f.putsなど ファイルに対する書き込み(1行ずつ、もしくは、入力レコード単位)
    ...
end

ファイルを閉じる

ファイルの読み書きが終わったら、ファイルを閉じなくてはいけません。例では、全て「File.open 〜ブロック〜 end」を用いています。このようにすると、ブロックが終了した後、自動的にファイルを閉じてくれます。また、「begin 〜ファイル処理〜 ensure 〜必ず実行される部位〜 end」の制御文を用いて必ずファイルを閉じるようにする書き方もあります。書き方は状況次第ですが、閉じることを忘れないような書き方を工夫した方が良いです。

begin
  f = File.open("aaa.txt")
  #ファイルfに対する処理...
ensure
  f.close
end

プログラム

test_fileread1.rb
#! /usr/bin/ruby

abort("#{ARGV[0]} does not exist.") if !File.exist?(ARGV[0])

File.open(ARGV[0]).each do |line|
  puts ($.).to_s+' '+line.chomp
end
test_fileread2.rb
#! /usr/bin/ruby

abort("#{ARGV[0]} does not exist.") if !File.exist?(ARGV[0])

sep = $/; $/ = '>'

File.open(ARGV[0]).each do |line|
  name = line.split(/\n/)[0]
  next if name == ">"
  puts name
  File.open(name, "w") do |f|
    f.puts '>'+line.gsub(">",'')
  end
end

$/ = sep

プログラム実行

test_data.fasta
>A1
1AAAAAAAAAAAAAAAAAAAAAAAAAAAAA
2AAAAAAAAAAAAAAAAAAAAAAAAAAAAA
>B2
1BBBBBBBBBBBBBBBBBBBBBBBBBBBBB
2BBBBBBBBBBBBBBBBBBBBBBBBBBBBB
>C3
1CCCCCCCCCCCCCCCCCCCCCCCCCCCCC
2CCCCCCCCCCCCCCCCCCCCCCCCCCCCC
test_fileread1
$ test_fileread1.rb test_data.fasta
1 >A1
2 1AAAAAAAAAAAAAAAAAAAAAAAAAAAAA
3 2AAAAAAAAAAAAAAAAAAAAAAAAAAAAA
4 >B2
5 1BBBBBBBBBBBBBBBBBBBBBBBBBBBBB
6 2BBBBBBBBBBBBBBBBBBBBBBBBBBBBB
...
test_fileread2
$ test_fileread2.rb test_data.fasta
A1
B2
C3
$cat A1
>A1
1AAAAAAAAAAAAAAAAAAAAAAAAAAAAA
2AAAAAAAAAAAAAAAAAAAAAAAAAAAAA

プログラムについて

test_fileread1.rbでは、ファイルの「読み込み」を確認しました。ファイルを読み込んで1行ずつ表示します。その際、先頭に行番号を追記しました。($.)はファイルから読み出された最後の行番号を保持します。先頭が’>’のものだけを取り出したい場合は、「(puts line.chomp;next) if /^>/」などのようにして正規表現で絞り込みを行うと良いと思います。また、一番最初でファイルの存在チェックを行っています。

test_fileread2.rbでは、ファイルの「読み込み」と「書き込み」を確認しました。通常は改行コードまで、つまり1行が読み取りの単位ですが、セパレータ($/)を「>」に変更することで(sep = $/; $/ = ‘>’…最後に戻します。$/ = sep)、FASTAなどのエントリー単位に読み出しを行うことが可能になります。今回は、エントリー単位で読み出し、さらにエントリー単位のファイルを作って1つ1つファイル出力を行っています。画面表示されるのは、処理しているエントリーの名前です。

スポンサーリンク