ホーム‎ > ‎

Perlを始めよう

PerlはLarry Wallさんが自分の仕事のために作り始めたスクリプト言語で、Unixとの親和性が高く、文字列処理に優れ、文法が柔軟なのが特徴です。Unix/Linuxシステムを使う人、動かす人には必須といってよいでしょう。少しずつ使っていくなかで、少しずつ学びながら、自ずと必要なことを身につけていくことができます。

Perlの本拠地

です。
The Comprehensive Perl Archive Network (CPAN) http://cpan.perl.org/
にはPerlで使えるスクリプトやモジュール等が大量に集積されています。本格的にPerlを使うようになると必ずお世話になります。

ミニマルPerlについて

Perlは一つのことをするのにたくさんの書き方があることが特徴で、いろいろな趣味やバックグラウンドを持つ人に受け入れやすい反面、最初から高い自由度を与えられるとかえって混乱したり戸惑ったりすることにもなりかねません。そこで、特にUnix/Linuxのコマンドやシェルスクリプトにある程度なじみがある人を対象に、自由度を制限し、スタートしやすく工夫されたのが

Tim Maher, 「ミニマルPerl〜Unix/LinuxユーザのためのPerl習得法」(オライリージャパン、2008)

にあるミニマルPerlです。これはあくまでも記法の自由度の制限であって、Perlの機能のサブセットではないので、安心して始めることができると思います。

文法要素の整理

文法要素のまとめとして、独立行政法人情報処理推進機構(IPA)が実施する情報処理技術者試験で用いられる
「試験で使用する情報技術に関する用語・プログラム言語など」
を参照します。
計算数学用ファイルサーバにおいてあるので、以下のリンクから取得してください。

(実習用PCからのみ。外部からは、上記の名前を検索してください。)
Perlについては、pp.11 -- 17に記載があります。
(以下ではこれのことを「解説」と呼びます。)
(この内容はあくまでも情報処理技術者試験での参照範囲ですので、Perl自体にはもっといろいろな機能があります。)

Perlはどこに?

Perlは伝統的なUnixにもともと含まれていたソフトウェアではないので、UnixのバージョンやLinuxのディストリビューションによっては、インストールされているディレクトリがまちまちだったり、別途インストールしなければならなかったりすることがあります。Ubuntuでは(他のほとんどのLinuxディストリビューションと同様)最初から入っています。どこにあるのか、確かめておきます。(この情報は後で使います。)

$ which perl

Perlのバージョン、その他の情報は

$ perl -V

で調べることができます。将来細かい機能を使い込んでいくと、バージョンやコンパイル時の条件によって動作が異なる場合があるので、そのときにはこの情報をもとにして調べていくことになります。

One liner

sedと同じように、Perlもコマンド行内に簡単なプログラムを与えることができ、それだけで結構重宝します。やってみましょう。

$ perl -wnl -e 'print;' file1 file2...

ここで "file1 file2..." というのは、複数のファイル(テキストファイルでないとこの場合は不都合ですが)の名前をスペースで区切って書き並べてよいということです。以下同様。

問:これはUnix/Linuxコマンドの何と同じような動作をするものか?

$ perl -wpl -e 's/^/   /g;' file1 file2...

文は ";"(セミコロン)で終端することに注意してください。

変数

Perlの変数にはいくつかのタイプがあり、それぞれ、名前(アルファベット、数字等で構成)の前に決まった記号をつけて表します。「解説」の「3. 変数」を見てください。
まず必要なのは値を一つ持つ”普通の”変数である「スカラ変数」とデフォルト入力"$_"です。

変数を使う際に、あらかじめ宣言したり領域を確保したりする必要はありません。すべて自動的に処理されます。

オプション

上のone linerの例で
-wnl
というおまじないがついていますが、これには以下の意味があります。

 -w 警告警告メッセージを有効にする 
 -n 読み込み(出力なし) $_にレコードを格納する読み込みループを要求
 -p 読み込んで出力 $_にレコードを格納してその内容に処理を施してから自動的に出力する読み込みループを要求
 -l 行末処理 print出力の末尾に改行を自動的に挿入。-n, -lと組み合わせると、入力レコードから改行を自動的に削除

それでは

$ perl -wpl -e '' file1 file2...

は何をするでしょうか?

スクリプト

シェルスクリプトのところで扱ったように、ファイルにプログラムを格納してコマンドとして扱うには、

  1. 1行目に "#! プログラム名"を入れる(ここで "$ which perl"の結果を使う)
  2. 2行目以下にそのプログラムで処理されるスクリプトを書く
  3. ファイルに実行可能属性を与える("chmod +x")

例:(適当なエディタでファイルにしてください。以下同様)

#! /usr/bin/perl
print "hello, perl\n";

明示的に改行を出力させるには "\n" を使います。(("\" は環境によっては半角の¥マークだったり半角の\(バックスラッシュ)だったりします。適宜読み替えてください。))

なお、特に、1行目のプログラム名のところに、オプションも与えることができます。
例えば

#! /usr/bin/perl -wnl
print;

を適当なファイルに格納し、"chmod +x"すると、超機能限定版 "cat" ができます。
オプション "-w" はいつもつけておくことを薦めます。

配列とハッシュ

配列(リストとも)全体は "@名前" で表し、各要素は "$名前[添字]"で表します。
括弧 (...) で括ることで配列を要素によって明示的に構成することもできます。

#! /usr/bin/perl -w
@fruits = ("apple", "orange", "lemon");
print "I love $fruits[1].\n";

($a, $b, $c) = @fruits;
print "You love $c.\n";

添字として数ではなく文字列をとることができます。これをハッシュ(連想配列とも)と呼びます。強力です。ハッシュ全体は "%名前" で参照し、各要素は "$名前{キー}"  で参照します。(ハッシュの場合添字をキーと呼ぶ)
括弧で括ってキーと値の組を明示的に与えてハッシュを構成することもできます。

#! /usr/bin/perl -w
%c = ("jp", "Japan", "fr", "France", "uk", "United Kingdom", "us", "United States");
print "jp is the ccTLD for $c{'jp'}.\n";
print "uk is the ccTLD for $c{'uk'}.\n";

演算子

「解説」の「4. 演算子」にあるように、普通の(C言語にならった)演算子が用意されています。

制御構造

「解説」の「5. 文」にある、普通のプログラム言語が備える制御構造がPerlにもあります。
ちょっと変わっているのは "foreach" で、「解説」の例にあるような単純なものだけでなく、ハッシュと組み合わせることでいろいろな使い方ができます。「解説」の「11. 配列・ハッシュ操作関数」を見てください。

#! /usr/bin/perl -w
%c = ("jp", "Japan", "fr", "France", "uk", "United Kingdom", "us", "United States");
foreach $k (keys %c) {
   print "$k is the ccTLD for $c{$k}.\n";
}

#! /usr/bin/perl -wnl
($gname, $gpass, $gid, $guser) = split(/:/, $_);
print "$gname -> $gid";

これは(ファイル名ggidとして)

$ ./ggid /etc/group

と使います。

問:何をしているのでしょうか?

splitというのは組み込みの関数で、第2引数で与えられた文字列を、第1引数で与えられた文字で分割した結果をリストにして返します。このような文字列処理を行う機構や関数が豊富に備わっていることもPerlの特徴です。

正規表現

Perlには強力な正規表現が備わっています。grepやsedと同様またはそれ以上の機能がありますが、一気に学ぶのは大変なので、ぼちぼちやりましょう。基本的な事項は、「解説」の「6. 正規表現」にあります。
Perlは、sedと同じように、正規表現にマッチした(またはマッチしない)行を見つけて、その行に対して処理を行う、という動作をさせることができます。(その処理が"print;"ならgrep相当の機能になるわけ)

One liners

$ perl -wnl -e '/RE/ and print;' file

/RE/の中のREには正規表現が入ります。("/"は2つともそのまま書く)これまでに扱ったgrepの例等を見て、適当に試してみてください。

$ perl -wnl -e '/RE/ or print;' file

では

$ perl -wnl -e '^$/ or print;' file

は何をしているでしょうか?

検索で大文字小文字を無視する ("grep -i")には

$ perl -wnl -e '/RE/i and print;' file

とします。
置き換えをする(sedのように)には

$ perl -wnl -e 's/RE/replacement/g;' file

とします。(sedの文法をほぼ横取りしている!)

実習

  1. Ubuntuのディレクトリ "/usr/bin" の中に、Perlで書かれたプログラムはいくつあるか。それぞれのサイズ(行数)はどれだけか。
  2. Perlを使って、FF(16進の九九)の表を作れ。

実行例のいくつかは1998年に麻生さんに作ってもらった初代Perl入門テキストから引用させていただきました(一部改変)。
Comments