読者です 読者をやめる 読者になる 読者になる

Ruby で特定のパターンが出現するまで簡単にファイルを読み飛ばす方法

テキストファイルの処理をしてると、たまに表題のようなことをやりたくなりますね。

ヘッダーの1行だけ読み飛ばすとか固定行数読み飛ばすだけならその行数の分だけ gets() を呼べばいいのですが、何行目に現れるかわからない特定のパターンまで読み飛ばすというのは、C 言語脳な僕には gets() して目的のパターンかどうか比較してそうでなければ次の行・・・みたいなループを書いてしまいがちです。

Ruby 脳的にはどうするのがいいかなと思っていたのですが、gets() の rs 引数としてその特定のパターンを渡せばよいようです。

すなわち、

aaaaa
bb
ccccc
ddd
eeeeeee
fff
<<<DATA
data 1
data 2
data 3
  :

という感じのファイルがあったとして、<<

open('data.txt') do |f|
  f.gets("\n<<<DATA\n")
     :
  # 本来の目的の処理
end

と1行で読み飛ばせてしまうことがわかりました。

"\n<<<DATA\n" を行の区切りとして、そこまでを一行として読み取ってしまうという荒業ですね。(そうでもない?)

前後の \n によって、その文字列だけからなる行があるということを意味しています。

逆に特定のパターンが行の途中に現れるとかだとすると \n を除かないといけません。
ただ、後ろの \n が無いと、本来の処理に入ってから一回だけゴミが渡されてきちゃうような気がしますので要注意かも。といっても gets() (引数なし)をもう一回呼べばいいだけですかね。

パターンとして正規表現が使えたら最強な気もしますが、rs のデフォルトが $/ ということはそれはできないのかな?


多分、年に2回くらい使うので忘れないようにメモ。