公開日:2008.03.05
ファイルのテキストを変換する - 2
この記事はRubyやirbなどの環境構築が終わっていることを前提としています。 まだ環境構築ができていない方は以下の記事を参照して構築してください。
では前回のプログラムの内容解説です。 まずプログラム全文は以下です。
ファイル名:AddLineNumber.rb
01 : # 読み込みファイルを開く
02 : readFile = File.open(ARGV[0])
03 :
04 : # 書き込みファイルを開く
05 : writeFile = File.open(ARGV[1], "w")
06 :
07 : # 読み込みファイルの中の文字列を全て取得
08 : readString = readFile.read
09 :
10 : # 文字列を一行ずつ繰り返して処理
11 : readString.each_with_index{ |line, index|
12 :
13 : # 書き込みファイルに行番号を出力
14 : writeFile.printf("%02d : ", index + 1)
15 :
16 : # 書き込みファイルに本来の文字列を出力
17 : writeFile.print(line)
18 : }
19 :
20 : # ファイルを閉じる
21 : readFile.close
22 : writeFile.close
23 :
24 : # 成功と表示
25 : print "成功"
このプログラム自身を使用して行番号を振っていますが、実際は入力していません。
ファイルの操作
ファイル操作の基本は「読み込み」と「書き込み」です。 でも本当の文房具のファイルもそうですが、読んだり書いたりするためにはファイルを開かなくては話になりません。 また、開いたら直すときには閉じないといけません。 これはプログラムの世界でも同じです。
今回は読み込んだファイルを別のファイルに出力します。 ですので読み込むファイル、書き込むファイルそれぞれに対して「開く」「閉じる」という操作をしなくてはなりません。 それが以下の部分です。
01 : # 読み込みファイルを開く
02 : readFile = File.open(ARGV[0])
03 :
04 : # 書き込みファイルを開く
05 : writeFile = File.open(ARGV[1], "w")
~ 中略 ~
23 : # ファイルを閉じる
24 : readFile.close
25 : writeFile.close
#の後ろのコメントでも書いていますが、例えば読み込み用ファイルを開くときには以下のようにします。
readFile = File.open(ARGV[0])
File.open(Fileクラスのopenメソッド)でARGV[0]に入っているファイル名のファイルを開きます。 開いた状態のファイルがそれぞれreadFile、writeFileに代入されます。 ファイルを開くときは読み込みモード、書き込みモードなどがありますので、書き込みモードの時は"w"というパラメータも指定しています。 省略すると読み込みモードになります。 また、開いたファイルは最後で2つとも閉じています。
ARGVとは
プログラムを実行したときに書いたパラメータが入ります。 前回の例で言うとARGV[0]にはAddLineNumber.rb、ARGV[1]にはAddLineNumber_new.rbというものが入ります。 ですので読み込みファイルとしてARGV[0]、書き込みファイルとしてARGV[1]を指定しています。
ファイル内容の読み込み
次に開いたファイルの内容を全て読み込むのが次の命令です。 readStringという変数に全て代入しています。
07 : # 読み込みファイルの中の文字列を全て取得
08 : readString = readFile.read
このreadStringは複数行に渡る文字列情報で、25行に渡るファイルの内容が全て入っています。 ですが、行番号を付加するためには一行ずつ処理する必要があります。 Rubyの文字列クラスにはまさにそのためのメソッドが用意されているのですが、それが次の部分です。
10 : # 文字列を一行ずつ繰り返して処理
11 : readString.each_with_index{ |line, index|
eachというメソッドもあるのですが、ここは今が何行目かの情報も得られるeach_with_indexを使用しています。 これはブロック構文というRubyの特徴的な文法の一つで、一行ごとに{}で囲まれた処理を繰り返して実行されます。 さらに実行の際、1行分の文字列をlineに、今の行番号をindexに代入してくれます。
ここから18行目までは読み込んだファイルの1行ずつに対して行う処理を書きます。 つまり行番号をつけながら、書き込み用ファイルに書き込む処理を書きます。
ファイルへの書き込み
読み込み用ファイルから一行ずつ読み込み、以下の変数に一行分の情報がセットされます。
index: 今読み込んだ行が何行目か(0から始まる)
line : 読み込んだ行の内容の文字列
二段階に処理を分けてやりましょう。
- 行番号を出力する(「01: 」というような形式で)
- 行番号の後ろに文字列を追記する
まず、1.行番号を出力する の処理はこちら
13 : # 書き込みファイルに行番号を出力
14 : writeFile.printf("%02d : ", index + 1)
writeFileのprintfはC言語などでもよく知られる文字列整形処理です。 数値を2桁で、1桁の場合は最初に0をつけるというルールが%02dです。 indexは0から始まっているので+1していることに注意してください。 その後に本来の文字列を追記します。
16 : # 書き込みファイルに本来の文字列を出力
17 : writeFile.print(line)
これが各行ごとに繰り返されるので目的を達成できるわけですね。
全てエラー無く実行できると、最後の命令により画面に「成功」と表示されて終わります。 エラーが発生するとエラーメッセージが出て処理は中断されます。
それではまた次回。
