新井です。

In message "[ruby-list:38056] ファイル書換え?"
  on 10 Aug 2003 00:02:14 +0900,
  中村文建 <tx6f-nkmr / asahi-net.or.jp> wrote:

> ▲質問:ファイルの上書きはどのようにするのでしょうか?
> あまりにも基本的な事だと思いますが、参考にするプログラムも分らず
> 周りに聞く人もいません。
> 参考になるパターン、実例を教えて下さい。

「最終的にやりたいこと」からはずれて説明をします。

(1) まず、元のファイルの内容を書き換えたい場合は一般的に以下
    のようにします。

while buf = ARGF.gets
  # buf を書き換え
  print buf
end

これで書き換えた内容が出力されるのでリダイレクトをすれば書き
換えたファイルが作成されます。(リダイレクトは Win でも可能で
す)

この後、リダイレクトしたファイルを元のファイルに手で上書きす
れば要件を満たします。

この手作業を自動的に行いたい場合は -i オプションを使用します。
(上のスクリプトが hoge.rb だとすると)

ruby -i hoge.rb 対象のファイル...

のように実行すると画面出力の内容を元ファイルに勝手に上書きし
てくれます。(-i では、ファイルを複数同時に指定できます)

ruby -i.bak hoge.rb 対象のファイル...

のように -i に続けて拡張子を指定すれば元のファイルをバックアッ
プしてくれます。

以下サンプルです。
--- hoge.rb
while buf = ARGF.gets
  # buf を書き換え
  buf.upcase!
  print buf
end
--- end of hoge.rb

以下実行例です。

echo aaa > aaa
echo bbb > bbb

ruby -i.bak hoge.rb aaa bbb

これで、aaa の内容が AAA に、bbb の内容が BBB になります。
(元ファイルは、aaa.bak 等に保存されます)


(2) 元の質問ではファイルの内容をイッキ読みして置換してますが、
    これをやるのも簡単です。gets の引数に nil を指定してあげます。
    (ARGF.read だと残念ながらうまく行きません)

while buf = ARGF.gets(nil)  # <- nil を指定
  # buf を書き換え
  buf.upcase!
  print buf
end

このスクリプトで上記と同じことをやれば同じ結果になります。試
してみてください。

「buf を書き換え」の部分を望みのものに変えてやれば要件を満たすと
思います。試してみてください。

# -p とか -0 とかのオプションを使えばさらに省略できるのですが、
# 本題と外れるので略

> data.scan(HTMLRegexp){|match|
>   comment, tag, tdata = match[0..2]
>   if comment                              # コメントにマッチした場合
>     p [ "Comment", comment ]
>   elsif tag                               # タグにマッチした場合
> 		tag.gsub!(/\w/){|matched| matched.downcase } 
>     p [ "Tag", tag ]
>   elsif tdata                             # テキストデータにマッチした場合
>     tdata.gsub!(/\s+/, " ")               # 空白をまとめる
>     tdata.sub!(/ $/, "")                  # 末尾の空白を削除する
>     p [ "TextData", tdata ] unless tdata.empty?  # 空でなければ出力する
>   end
> 
> }

この内容はまた別の話だと思うのでとりあえず割愛。

# 暇だ。LL 行きたかったなあ

--
新井康司 (Koji Arai)