Just do IT

思うは招く

テキストファイルからデータを読み込み、いろんな処理をして書き込む Ruby基礎#24

お題

テキストファイルからデータを読み込み、次の条件に従って上書きをするスクリプトを作成せよ。

  • ファイル中の行を逆順に並べ替える
  • ファイル中の最初の1行だけ残して他は削除
  • ファイル中の最後の1行だけ残して他は削除

回答

# ファイル中の行を逆順に並べ替える
def reverse(file)
  open(file, "r+") do |f|
    lines = f.readlines
    f.rewind
    f.truncate(0)
    f.write(lines.reverse.join)
  end
end
reverse(ARGV[0])

# ファイル中の最初の1行だけ残して他は削除
def first_one(file)
  open(file, "r+") do |f|
    lines = f.readlines
    f.rewind
    f.truncate(0)
    f.write lines[0]
  end
end
first_one(ARGV[0])

# ファイル中の最後の1行だけ残して他は削除
def last_one(file)
  open(file, "r+") do |f|
    lines = f.readlines
    f.rewind
    f.truncate(0)
    f.write(lines[-1])
  end
end
last_one(ARGV[0])

説明

先に告白。2問目以降がわからず答えを見てしまった。

# ファイル中の行を逆順に並べ替える
def reverse(file)
  open(file, "r+") do |f|
    lines = f.readlines
    f.rewind
    f.truncate(0)
    f.write(lines.reverse.join)
  end
end
reverse(ARGV[0])

openでファイルを開く。読み込み、書き込み用として開く意味でオプションr+をつける。 readlinesで一行ずつ読み込み、配列にそれぞれ格納。

rewindでファイルポインタを先頭に戻す。 truncate(0)でファイルサイズを0にする。いわば空っぽにする削除みたいなもの。

最後に、取得したlinesにreverseメソッドをかけて逆順にし、joinで文字列になおしてファイル書き込み。

他の2つはf.writeの部分が違うだけ。

以下だと配列linesの先頭要素だけをファイルに書き込む。

f.write(lines[0])

これは最後の要素だけ。

f.write(lines[-1])

学び

IOクラスの使い方にようやく慣れてきた。 答え見ちゃったけど。