Perl関係

目次

文字列処理

文字列結合

ピリオド(.)でつなぐ[9]

置換

[8]

【例】変数$hogeの中のfooを全てbarに置換
$hoge =~ s/foo/bar/g;

正規表現

正規表現にマッチするかどうかを判定するには =~ 演算子を用いる[05,pp194-200][12]。正規表現はスラッシュではさんで指定する。但し、変数にスラッシュを含めると正規表現として認識してくれないらしい。

【例】
$ cat test_good.pl
#!/usr/bin/perl
$pattern='^hoge.*';
$str='hoge';
if ($str =~ '/$pattern/) {
  print "Match!\n";
} else {
  print "Not Match!\n";
}
$ ./test_good.pl
Match!
$ cat test_bad.pl
#!/usr/bin/perl
$pattern=''/^hoge.*/';
$str='hoge';
if ($str =~ '$pattern) {
  print "Match!\n";
} else {
  print "Not Match!\n";
}
$ ./test_bad.pl
Not Match!

変数

変数の種類

変数には1つの値だけを持つ単純な変数(スカラー変数)とキーと値の対を1つ以上持つ配列変数とがある。更に配列変数はキーに数値だけを使った配列と、文字列も使える配列(連想配列)とがある。定義・参照の際、変数名の頭には型を示す文字を冠する。各変数型を示す文字は以下の通り[5, p95]

変数型を示す文字 変数型 内容
$ スカラー変数 単一の数値や文字列を収めた変数。
--- var_sca.pl
#!/usr/bin/perl
$hoge = "foo123";
print "$hoge\n";
exit;
---
$ ./var_sca.pl
foo123
@ 配列変数 「キー」と「値」の組を0個以上持つ変数。
キーに使われる値は0以上の整数。
--- var_array.pl
#!/usr/bin/perl
@array = ("御堂筋","谷町","四つ橋","中央");
$i = 0;
while ($array[$i]) {
    print "[$i] = $array[$i]\n";
    $i++;
}
exit;
---
$ ./var_array.pl
[0] = 御堂筋
[1] = 谷町
[2] = 四つ橋
[3] = 中央
% 連想配列変数(ハッシュ) 「キー」と「値」の組を0個以上持つ変数。
キーには文字列および数値が使用可能。
--- var_hash.pl
#!/usr/bin/perl
%hash = ("赤"=>"御堂筋","紫"=>"谷町","青"=>"四つ橋","緑"=>"中央");
foreach $key (keys(%hash)) {
    print "[$key] = $hash{$key}\n";
}
exit;
---
$ ./var_hash.pl
[青] = 四つ橋
[紫] = 谷町
[赤] = 御堂筋
[緑] = 中央

コマンドライン引数の参照

$ARGV[0],$ARGV[1],...で参照。最初の引数が0番。実行可能スクリプトでも同様。

perl hoge.pl hiki1 hiki2
→hoge.pl 中で 第1引数(hiki1)を参照するには $ARGV[0]を、第2引数(hiki2)を参照するには $ARGV[1]を指定。
    

ループ処理内での変数

whileなどの繰り返し処理で、特に指定がなければ$_に代入されて処理が回される[3 2部 Perl言語仕様 - 変数]

変数宣言

単純にスクリプト内で定義した変数の内容は、定義を記述した場所に関わらずスクリプト全体で利用可能なグローバル変数となる。スクリプト内で定義したサブルーチンにおいて変数の内容を変更すれば、変更内容はサブルーチン内だけではなくグローバル変数に反映される[5, pp147-148]

【スクリプト例】(test.pl)
#!/usr/bin/perl
sub subr{
  $name = "Hyde";
  print "His name in the subroutine is $name.¥n";
}
$name = "Jekyll";
print "His name before executing the subroutine is $name.¥n";
&subr($name);
print "His name after executing the subroutine is $name.¥n";
exit;
【実行例】
$ ./test.pl
His name before executing the subroutine is Jekyll. ← サブルーチン実行前
His name in the subroutine is Hyde. ← サブルーチン内で値が変更された
His name after executing the subroutine is Hyde. ← サブルーチン実行後も変更保持
    

サブルーチン内のみ有効な変数を作るには my 関数を用いる[5, pp149-150]

【スクリプト例】(test.pl)
#!/usr/bin/perl
sub subr{
  my $name = "Hyde";
  print "His name in the subroutine is $name.¥n";
}
$name = "Jekyll";
print "His name before executing the subroutine is $name.¥n";
&subr($name);
print "His name after executing the subroutine is $name.¥n";
exit;
【実行例】
$ ./test.pl
His name before executing the subroutine is Jekyll. ← サブルーチン実行前
His name in the subroutine is Hyde. ← $name の定義はサブルーチン内のみ有効
His name after executing the subroutine is Jekyll. ← サブルーチン実行後もグローバル変数である $name の値は変更されていない
    

配列関係

配列のキー一覧や個数を得るには keys 関数を、配列要素の値や個数を得るには values 関数を用いる[5, pp104-105]。個数については、単に配列変数をスカラー変数に代入するだけでも得られる

関数 代入先
配列 スカラー変数
keys キー一覧 要素数
values 値一覧
【書式】
%キー格納配列変数 = keys %配列変数
$要素数格納変数 = keys %配列変数

【例】
<スクリプト>test.pl
#!/usr/bin/perl
%lines = ("御堂筋"=>"赤","谷町"=>"紫","四つ橋"=>"水色","中央"=>"緑","千日前"=>"桃","堺筋"=>"茶","長堀鶴見緑地"=>"黄緑","今里筋"=>"橙");
$linecount = keys %lines;
foreach $key (keys(%lines)) {
    print "$key ";
}
print "\n";
print keys(%lines),"\n";
foreach $val (values(%lines)) {
    print "$val ";
}
print "\n";
print values(%lines),"\n";
print "大阪市営地下鉄には $linecount つの線があります。\n";
exit;

<実行結果>
$ ./test.pl
中央 四つ橋 堺筋 千日前 今里筋 長堀鶴見緑地 御堂筋 谷町 
中央四つ橋堺筋千日前今里筋長堀鶴見緑地御堂筋谷町
緑 水色 茶 桃 橙 黄緑 赤 紫 
緑水色茶桃橙黄緑赤紫
大阪市営地下鉄には 8 つの線があります。
    

環境変数

$ENV{環境変数名} = "環境変数値";[10]

真偽値について

Perlでは真偽値(boolean)というデータ型はなく、下記値以外はtrueと判定されるとのこと[14][15]

繰り返し処理

[5, pp126-134]

for (初期条件,継続条件,継続処理) {
  処理内容;
}
foreach 変数 (初期値..終了値) {
  処理内容;
}
while (継続条件) {
  処理内容;
}
do {
  処理内容;
} while (継続条件)
until (終了条件) {
  処理内容;
}
do {
  処理内容;
} until (終了条件)
  

外部スクリプト類の利用

モジュール類を利用できるようにするには use 関数を用いる。

モジュールuse例
記述 内容
use strict; 宣言なく変数を使うことができないようにする。
use CGI; CGIに関わる機能を利用できるようにする。

ユーザが定義した別のスクリプトファイルを取り込んで利用するには require 関数を使う。呼び出される側のスクリプトの最後には「1;」を記しておき、戻り値が1(真)となるようにしておく必要がある[5, pp173-175]

【例1】変数定義を別スクリプトから呼び出す
【呼び出し側】(main.pl)
#!/usr/bin/perl
use strict; # 宣言なく変数を使うことができないようにする
require "sub.pl"; # カレントディレクトリからの相対パスで表記した場合
our $var;
print "var = $var\n";

【呼び出される側】(sub.pl)
our $var = "hogehoge";
1;
【例2】関数定義を別スクリプトから呼び出す
【呼び出し側】(main.pl)
#!/usr/bin/perl
require 'sub.pl';
func1;

【呼び出される側】(sub.pl)
sub func1 {
  print "Hello World from subpackage!\n";
}
1;

なお、例2の方法だと同じサブルーチン(関数)名があった場合に問題が生じる(前出のものは後出のもので上書きされる?)。それを避けるには呼び出されるパッケージに名前を付ける[7]

【例3】呼び出すパッケージに名前を付ける
【呼び出し側】(main.pl)
#!/usr/bin/perl
require "sub1.pl";
subpackage1::func();
subpackage2::func();

【呼び出される側】(sub1.pl)
package subpackage1;
sub func {
  print "Hello World from subpackage1!\n";
}
1;
【呼び出される側】(sub2.pl)
package subpackage1;
sub func {
  print "Good morning World from subpackage2!\n";
}
1;

コマンドラインオプション

以下にperlコマンドのオプションを示す[2, 第4回][6]

-v
バージョン情報を出力して終了。
-h
ヘルプ(コマンドラインオプションの説明)を出力して終了。
-e
指定文字列をプログラムと解釈して実行する。簡単な処理の実行には便利。
【例】
perl -e 'print "hoge"' →「hoge」が出力される
-n
指定プログラムが、'while (<>) { ... }' で囲まれているのと同等の処理を行う。 つまり、入力ファイル(または標準入力からの入力)各行に対して指定処理を行う。
-p
-nと同等。但し、処理行の出力も行う(既定では標準出力への出力)。 -iオプションと組み合わせると、単に出力するだけではなくファイルの編集(置換)を行うことができる。
shell> perl -p -e 'print ++$i, ": "' ←プログラム文字列の後に何も記さなければ標準入力からの入力が処理対象
hogehoge
1: hogehoge
fugafuga
2: fugafuga
nyannyan
3: nyannyan
^Z ←Ctrl + z を入力
[1]+  Stopped                 perl -p -e 'print ++$i, ": "'
shell> perl -p -e 'print ++$i, ": "' ~/hoge.txt ←プログラム文字列の後にファイル名を指定した場合
hogehoge
fugafuga
wanwan

-i拡張子
処理結果を指定ファイルに書き込む。拡張子を指定した場合は、処理前の元ファイルは元のファイル名+拡張子というファイル名で保存される。指定がなければ元ファイルのバックアップは行われない。
-w
様々な警告を出力してくれる。

サブルーチン

サブルーチンの定義は下記書式にて行う。

sub サブルーチン名 {
  処理内容;
}
  

サブルーチンの呼び出しは「&サブルーチン名(引数)」の書式で行う。

【例】
<スクリプト>test.pl
#!/usr/bin/perl

sub subr {
  print "Now $name is in a subroutine.¥n";
}
$name = 'Taro';
&subr($name);
exit;
<実行例>
$ ./test.pl
Now Taro is in a subroutine.
  

ファイルシステム関係

ファイル・ディレクトリの存在確認

-e ファイル・ディレクトリ名で指定したファイルまたはディレクトリが存在するかどうかを判定する。ファイルである場合にのみtrueを返して欲しい場合は-f ファイル名を用いる[9]

$ ls -l
合計 8
-rwxrwxr-x 1 user user  545  6月 29 09:52 2015 test.pl
-rw-rw-r-- 1 user user    0  6月 29 09:55 2015 test.txt
drwxrwxr-x 2 user user 4096  6月 29 09:55 2015 testdir
$ cat test.pl
#!/usr/bin/perl
$file="test.txt";
$dir="testdir";
if (-e $file) {
  print "The file or directory ($file) was found!\n";
} else {
  print "Such file or directory ($file) was not found!\n";
}
if (-e $dir) {
  print "The file or directory ($dir) was found!\n";
} else {
  print "Such file or directory ($dir) was not found!\n";
}
if (-f $file) {
  print "The file ($file) found!\n";
} else {
  print "Such file ($file) was not found!\n";
}
if (-f $dir) {
  print "The file ($dir) found!\n";
} else {
  print "Such file ($dir) was not found!\n";
}
$ ./test.pl
The file or directory (test.txt) was found!
Such file or directory (testdir) was not found!
The file (test.txt) found!
Such file (testdir) was not found! ←testdirはファイルではなくディレクトリ

ディレクトリ内のファイルリスト取得

opendirでディレクトリを開き、readdirでディレクトリ内のファイル名を一つずつ読み取り、closedirでディレクトリを閉じる。または、readdirの結果受け取り先として配列変数を指定すると、対象ディレクトリ内の全ファイル名リストが配列に格納される[9]

ディレクトリの作成

mkdirはディレクトリを作成する[5, pp164,397][12]

【書式】
mkdir 作成ディレクトリ名, 許可モード;

【返り値】
ディレクトリ削除に成功→true
ディレクトリ削除に失敗→falseを返し、$!(error)をセット
作成ディレクトリ名
作成するディレクトリの名前を指定する。途中の階層のディレクトリは存在している必要がある。途中階層のディレクトリがなければ合わせて作成する(=UNIXコマンドのmkdir -pに相当)にはFile:Path モジュールのmake_path関数を用いる。
許可モード
作成するディレクトリの許可モードを3桁の数値で指定する。この値にumaskの修正を加えた値に許可モードが設定される。指定を省略した場合の既定値は777。

ディレクトリの削除

rmdirはディレクトリの削除を行う。但しこの関数はディレクトリの中身が空でないと削除は行わない。中身があってもディレクトリごと削除したい場合は File:Path モジュールのremove_tree関数を用いる。旧式のrmtreeでも動作は同じだが若干引数指定方法などが異なる[5, pp164-165][12][13]

【書式】
rmdir 削除対象ディレクトリ名

【返り値】
ディレクトリ削除に成功→true
ディレクトリ削除に失敗→falseを返し、$!(error)をセット
【書式】
use File::Path;
remove_tree(削除対象ディレクトリ名,オプション指定連想配列);

【返り値】
指定された全ファイルの削除に成功→削除に成功したファイル数
指定された一つ以上のファイル削除に失敗→falseを返し、$!(error)をセット

【例】
use File::Path 'remove_tree'; ←デフォルトでremove_treeはexportされないらしく明示的に指定が必要とのこと
remove_tree('hoge.txt','fuga.txt', {
  verbose => 1,
  error => \my $err_list,
});

remove_treeのオプション

verbose=>真偽値
true(1など)を指定すると、削除した各ファイルのファイル名を表示する。指定がない場合の既定値はfalse(0)。
safe=>真偽値
When set to a true value, will cause remove_tree to skip the files for which the process lacks the required privileges needed to delete files, such as delete privileges on VMS. In other words, the code will make no attempt to alter file permissions. Thus, if the process is interrupted, no filesystem object will be left in a more permissive mode.
keep_root=>真偽値
true(1など)を指定すると、指定したディレクトリ自身を除く全てのファイルおよびサブディレクトリを消去する。これはアプリケーションの一時データディレクトリを一掃する時などに便利。
result=>変数名
このオプションを指定すると、指定した変数に消去した各ファイル名を要素とする配列が代入される。消去されたファイルがなかった場合は空配列が代入される。このオプションはverboseオプションの変わりとしても使える。
error=>変数名
このオプションを指定すると、指定した変数に発生したエラーの内容を要素とする配列が代入される。 削除という操作は作成という操作よりずっと危険な操作である。場合によっては、プログラムを強制終了するしか正常な操作による操作方法がないような危険を伴うこともある。このオプションを使うと、捕捉可能なエラーを全てとらえ、制御できなくなった時は強制終了するのに使える。これは最も安全な使い方である。

アルファベット順コマンド一覧