#!/usr/local/bin/perl while (<>) { # 標準入力から1行づつ読んで以下を処理 s/1/1/go; # 1 を 1 に換えます。g = 1行に 2個以上あっても処理 s/2/2/go; # 2 を 2 に換えます。この処理は 同じ $_ に対して実行 s/3/3/o; # 3 を 3 に換えます。 print; # 結果を印刷します。 } # while の終了です。
g = grobal (1 行の中で該当する全部を変換する。) o = one time (検索するパターンが、変数でないので Perl に 1 度 だけ、コンパイルさせる。処理速度が速くなる。)となっている。オプションがある場合と無い場合の違いについて、 実験してみると良い。
p5-0.dat を以下の用に EUC コードで作り、実行する。
123456 全角の文字 123456 123456 全角の文字 123456 112233445566 半角の文字 112233445566
% p5-0.pl < p5-0.dat 123456 全角の文字 123456 123456 全角の文字 123456 112233445566 半角の文字 112233445566 %のように 3 は、行の最初に現れた 3 のみ処理をしている。
p5-0.plのように変換規則を並べれば良いので、処理時間を特に 気にしなければ簡単にプログラムが作れます。処理時間を調べたい時には、
% time p5-0.pl < p5-0.dat
でできる。0.020u 0.060s 0:00.09 は それぞれ user の使用した時間、system が利用した時間、その合計です。時間の単位は 秒です。
#!/usr/local/bin/perl $_ = 's9510245 斎藤 理一郎 125 24 35 Saitou'; # $_ を定義 print /郎 (.*)Saitou/,"\n"; # 郎 と Saitou の間にある部分を印刷。 @a = /郎 (.*)Saitou/; print @a, "\n"; # ( ) の部分は、配列 @a に入る。 print /.9510(.*)/,"\n"; # . は任意の1文字で、9510に続く行の残りを印刷 print /[a-z]9510(.*)/,"\n";# 最初の1文字は、a-z の文字に限定する。 print /\w9510(.*)/,"\n";# これでも可。\w はアルファベット文字を指す。 print /[a-z]9[45]10(.*)/,"\n"; # 9410 か 9510 のみ印刷。
. は任意の1文字である。
* は0回以上の繰り返しである。従って、.* は 任意の文字列 となる。
+ は 1 回以上の繰り返しである。
[...] は その中から範囲で選択となる。[0-9]+ の様に記すと、数 字の繰り返しになる。これは\d (数字) で置き換えられる。また [a-z] は \w (アルファベット文字 と _) で置き換えられる。この ような表現は正規表 現と呼ばれる。詳しくは、マニュアルを参考にして下さい。
特に検索部分を 変数に代入する場合には、($hensuu) = / ... / を 用いる。例えば file=a.eps を取り出したい場合には、= の前 後に space がある可能性に注意すれば、
($file) = /file[ ]*=[ ]*(.*).eps/ ; # (.*) が検索部分。[ ]* は可能なスペースの部分。
と書けば良い。($file) の (...) がないと、true or false が入る。
if(/パターン/){...} # パターン が あったら {...} を処理。
という文で行われる。置換をして処理することもできる。
if(s/パターン/置換/){...} # パターンがあったら置換を行い {...} を処理。
これは、パターンがあった場合には、/パターン/ が、if の文で 1(真) を与え、 また s/パターン/置換/ によって置換がうまくできた場合には、if の文で 1(真) を与えるからである。(print /パターン/; で確かめよ。)
#!/usr/local/bin/perl $_ = 's9510245 斎藤 理一郎 125 24 35 Saitou'; # $_ を定義 # もし $_ に Saitou があれば あったことを印刷。 if (/Saitou/) { print "Saitou san is found.\n" } # もし $_ に Saitou があれば Saitou を Saito に 変換して印刷。 if (s/Saitou/Saito/) { print "Found: ==> ",$_,"\n"} # こういう文法も ok です。この場合でも 置換をさきにします。 print "Found: ==> ",$_,"\n" if (s/Saito/Saitoh/); # /Saitoh/ がある場合にはどんな値を返すかを示します。 print /Saitoh/,"\n"; # /Saitou/ はありません。この場合にはどんな値を返すかを示します。 print /Saitou/,"\n";
% p5-2.pl Saitou san is found. Found: ==> s9510245 斎藤 理一郎 125 24 35 Saito Found: ==> s9510245 斎藤 理一郎 125 24 35 Saitoh 1 <== パターンばない場合には、何も返しません。 %