2.10.4. ファイル操作#

2.10.4.1. ファイルの読み取り#

ファイルを開いてデータを読み込むには、open 関数を使い、読み取りモード < で開きます。ファイルを開いた後、その情報はファイルハンドルに保存されます。ファイルハンドルの名前は任意ですが、ここでは $fh を使用しています。ファイルが存在しない場合に備えて or die を使ってエラーを表示するのが一般的です。処理が終わったら close 関数でファイルを閉じます。

例えば、sample.pdb ファイルを 1 行ずつ処理し、行が ATOM で始まる場合に出力するコードは次の通りです。

open(my $fh, "<", "./sample.pdb") or die "Cannot open file: $!";

while (my $buff = <$fh>) {
  chomp($buff);
  if ($buff =~ /^ATOM/) {
    print $buff;
  }
}

close($fh);

2.10.4.2. ファイルの書き込み#

ファイルにデータを書き込む場合は、書き込みモード > または追記モード >> で開きます。

  • 書き込みモード >:ファイルを新規作成。既存ファイルがあれば内容は破棄されます。

  • 追記モード >>:既存ファイルの末尾に追加。存在しない場合は新規作成されます。

open(my $fh, ">", "filename.txt") or die "Can"t open file: $!";

print $fh "Hello,\n"; 
print $fh "World.\n";

close($fh);

複数のファイルに書き込む場合も、それぞれのファイルを個別に開けば問題ありません。

my $data = [];
$data->[0]->{key} = "cds";
$data->[0]->{seq} = "accacgcagtcatgctatcgtcagt";
$data->[1]->{key} = "rna";
$data->[1]->{seq} = "accacgcacactttcattttctatcagt";

open(my $cdsfh, ">", "./CDS.txt") or die;
open(my $rnafh, ">", "./RNA.txt") or die;

for (my $i = 0; $i < @{$data}; $i++) {
  if ($data->[$i]->{key} eq "cds") {
    print $cdsfh $data->[$i]->{seq};
  } else {
    print $rnafh $data->[$i]->{seq};
  }
}

close($cdsfh);
close($rnafh);

2.10.4.3. gzip 圧縮ファイルの読み書き#

gzip 形式で圧縮されたファイルを扱うには、Perl の Compress::Zlib モジュールを使用します。ファイルを開く際には gzopen を使い、処理が終わったら gzclose で閉じます。ファイルの内容を 1 行ずつ読み取る場合は、gzreadline 関数を利用します。

use Compress::Zlib;

my $fh = gzopen("sample.fa.gz", "rb") or die "File not found.";

while(($data_size= $fh->gzreadline($buff)) > 0) {
    print($buff)
}

$fh->gzclose();

ファイルへの書き込みは gzwrite 関数を使用します。

use Compress::Zlib;

my $fh = gzopen("output.fa.gz", "wb") or die "Could not create file.";

$fh->gzwrite(">Seq1\nGCTGATCGAGTCGATCGATGCAGCTAGGT\n");
$fh->gzwrite(">Seq2\nTCGATTATATGCTAGTCGATGCTTTCGATGCGC\n");
$fh->gzwrite(">Seq3\nGCTGAATCGCTATTATATGCATGCATGTCTGCAGCTAGGC\n");

$fh->gzclose();

2.10.4.4. ディレクトリ操作#

ディレクトリの作成と削除も Perl の関数を通して行えます。ディレクトリの作成は、mkdir 関数を利用します。

my $path = "/home/user/tmp_dir";

if (-d $path) {
   print "The directory exists.\n";
} else {
   mkdir $path;
}

ディレクトリの削除は rmdir 関数を使用します。なお、ディレクトリ内にファイルが残っている場合は削除できないため、先に unlink でファイルを削除してから rmdir を使います。

unlink(glob("$path/*"));
rmdir $path;

2.10.4.5. ファイル一覧の取得#

ディレクトリ内のファイル一覧を取得するには opendirreaddir を使用します。

opendir(my $dh, "./");
foreach(my $f = readdir($dh)){
    print "$f";
}
closedir($dh);

特定の拡張子を持つファイルのみ取得する場合は glob が便利です。

my @pdb_files = glob "*.pdb";
foreach my $file (@pdb_files) {
    print "$file\n";
}