Perl基礎の基礎::ファイルを処理する †復習 †今までの2課では、プログラムのファイルに書かれたことを実行してきました。使用したのはプログラムファイル、xxxx.plのみで、その実行は、Perl xxxx.pl でした。つまり、必用な情報はすべて、プログラムファイルに書かれていたのです。 学習内容 †この課では、プログラムフィルから、他のファイルの中にあるデータを処理することを学習します。
使用するプログラムと実行コマンド(命令) †
# Last Update: June 22, 2006
# データファイル内のアルファベットをすべて小文字にして印刷する。
# usage: perl komoji.pl xxxx.txt
# copyright (2006) Tomonori Nagano & Kenji Kitao
while(<>){ # 外部ファイルを1行ずつ読み込む
print lc($_) ; # lower caseに変更し、それを印刷する
} # 最後の行まで読めば終える。
プログラムの解説 †komoji.plで、sample.txtの英語の文章の文字をすべて小文字にします。 データのファイルは、テキストファイルでなければなりません。つまり、文字以外の制御コードの入っていないファイルです。間違わないように、拡張子は.txtとしておきます。ワードのファイルなどは制御コードが入っているので無理です。エディタで作成した英数字のテキストを使用します。 lc()はPerlに元々備え付けられている約束ごと(ファンクション)で、すべての文字を小文字にしています。 sample.txtの中身は以下の通りです。 Language In Ireland The Republic of Ireland is officially bilingual, with its two languages being English and Irish or Irish Gaelic. Perl komoji.pl sample.txt > komoji-out.txt で、実行します。 プリントアウトは、自動的に作成されたkomoji-out.txtというファイルに以下のように印刷されます。 language in ireland the republic of ireland is officially bilingual, with its two languages being english and irish or irish gaelic. 一般的に、Perlのプログラムが実際にどのように処理しているかを確かめるために、最初は小さいファイルを処理します。その結果を自分の目でよく確かめて、大丈夫であれば,始めて大きなファイルを処理をします。その他にも、複雑なプログラムになれば、デバグ(バグの処理を行毎に行う事)をすることもあります。 While (<>)のコマンドは、他のファイルのデータを1行ずつ読み込んで、処理するももので、最後の行を読みこんで処理すれば終えます。この場合の行とは、データに改行シンボルのあるところまでです。 最初の行を読み込んで、小文字にして印刷します。それから2行目を読み込んで小文字にして印刷します。このテキストは2行ですので、これで終わりです。このように同じことを繰り返しする操作をループと読んでいます。 通常、<>の間にはファイルハンドルと呼ばれるファイルへのあだ名のようなものが書かれます。省略されている場合は、デフォルト(default)のファイル(最も最近に処理されたファイル)を自動的に指定するようになっています。 それでは、Sample2.txt やsample3.txtなどの大きなファイルを処理しましょう。 perl komoji.pl sample2.txt Perlは比較的簡単なスクリプトでも、高度なプログラム言語(C++やJavaなど)と同じぐらいに高速な処理ができます。sample3.txtは比較的大きいファイルですが、処理が一瞬でできるのがわかります。 では、2つのファイルを同時に処理したい時にはどうすればよいのでしょうか。while(<>)のコマンドは、1つ目のファイルが終わったら、自動的に続きのファイルがあるかどうかを確かめます。もしファイルがあれば、引き続き2つ目のファイルを処理します。もしファイルがなければ、自動的に終了します。ですので、2つ以上のファイルを処理するコマンドは、 perl komoji.pl sample.txt sample2.txt となります。ただ、1つのファイルでプリントアウトされるので、どこが2つのファイルの切れ目かは知っていないと、後で困ります。 今度はすべての文字を大文字にしましょう。omoji.pl を使用します。 # Last Update: June 22, 2006
# データファイル内のアルファベットをすべて小文字にして印刷する。
# usage: perl omoji.pl xxxx.txt
# copyright (2006) Tomonori Nagano & Kenji Kitao
while(<>){ # 外部ファイルを1行ずつ読み込む
print uc($_) ; # upper caseに変更し、それを印刷する
} # 最後の行まで読めば終える。
小文字にするプログラムと異なるのは、lc() とuc()で、lower case とupper caseの違いのみです。これだけで、こんなに大きな結果の違いを出します。これはコンピュータにすでに理解させてあるファンクションを利用しているので、このような事ができるのです。 練習問題 †練習1 †sample.txtとsample2.txtを、まずすべて小文字にして、それから、すべて大文字にして、両方のテキストを印刷せよ。プログラム名は、komojiOmoji.plとする。 まとめ †
課外活動 †komojiOmoji.plでは、1行ずつ小文字にし、それから大文字にしました。アウトプットをファイルに印刷すれば、エディタで、すべて小文字のテキストと大文字のテキストにわけることは、データが小さければさほど難しくはありません。 しかし、データが大きく、小文字のみのテキストと大文字のみのテキストのみを作成したい場合には、課外のフォルダにある。komojiOmoji2.plを使用してください。ただ、中を見れば多少は理解できますが、高度なプログラムなので、ここでは解説しません。ただ、このような複雑なプログラムを作成しなくとも、komoji.plとomoji.plを2度実行すれば同じ結果が出ますし、さほど作業も多くないですね。 プログラムのみを作成するのではなく、いかに求めるアウトプットが容易に得るかを考えてください。そもそもプログラムを作成するのは、手作業ですると大変な労力になり、正確にできないからです。プログラムにのめりこんで、初心を忘れないようにしてください。プログラムを作成する方が、手作業より困難な場合は、手作業ですればよいし、簡単なプログラムを数回実行する方が容易な場合は、プログラムを作成するより、その方法を選ぶのが賢明です。 解答と解説 †解答と解説 1 †while(<>){ # ファイルの中身を1行ずつ読み込む
print lc($_) ; # 小文字にして、それを印刷する
print uc($_) ; # 大文字にして、それを印刷する
} # 最後の行まで読めば終える。
或いは、 while(<>){ # ファイルの中身を1行ずつ読み込む
$lower .= lc($_) ; #小文字にして$lowerという変数に保存
$upper .= uc($_) ; # 大文字にして$lowerという変数に保存
}
print $lower ; # $lowerを印刷する。
print $upper ; # $upperを印刷する
一番単純な方法は、先ほどのlc()とuc()のコマンドを両方使った以下のようなプログラムです。 while(<>){ # ファイルの中身を1行ずつ読み込む
print lc($_) ; # 小文字にして、それを印刷する
print uc($_) ; # 大文字にして、それを印刷する
} # 最後の行まで読めば終える。
ただ、この方法だと、下記のように、角行毎に小文字と大文字が繰り返した印刷になります。 language in ireland LANGUAGE IN IRELAND the republic of ireland is officially bilingual, with its two languages being english and irish or irish gaelic. THE REPUBLIC OF IRELAND IS OFFICIALLY BILINGUAL, WITH ITS TWO LANGUAGES BEING ENGLISH AND IRISH OR IRISH GAELIC. これは、データファイルの英文を1行ずつ読み込み、行を小文字にして印刷し、その直後に同じ行をすべて大文字にして印刷しているからです。この「小文字に変換―印刷」と「大文字に変換―印刷」を最後の行まで行毎に繰り返しています。 では、大文字のと小文字の文を分けて印刷したい場合はどうすればいいのでしょう?下記のプログラムは大文字と小文字の文を分けて印刷するスクリプトのサンプルです。 while(<>){ # ファイルの中身を1行ずつ読み込む
$lower .= lc($_) ; #小文字にして$lowerという変数に保存
$upper .= uc($_) ; # 大文字にして$lowerという変数に保存
}
print $lower ; # $lowerを印刷する。
print $upper ; # $upperを印刷する
このプログラムでは新たに、$lowerと$upperという変数を使っています。変数の値は、角行を小文字に変換した値を取ります。前課で学習した通り、変数に値を与えるときは=(イコールマーク)を使いますが、この場合は、変数に値を「与える」のではなく、値を「加えて」いかなければなりません。そうしないと、前の行で与えた値が上書きされて消されてしまうからです。 そのため、ここでは.=(ピリオドとイコール)を使って、変数に値を加えています。こうする事により、すでに変数に与えられている値を上書きする事無く、新しい値を追加する事ができます。 最後の2行では、全ての行を読み取った$lowerと$upperを印刷しています。 |