1. ホーム
  2. スクリプト・コラム
  3. パール

Perlファイルの読み書きの学習ノート

2022-01-17 11:54:52

I. ファイルのオープンとクローズ

この構文は、open (filevar, filename) で、filevar はファイルハンドル、またはプログラムでファイルを表すために使用するコード、 filename はファイル名で、パスは相対パスでも絶対パスでもかまいません。

コピーコード コードは以下の通りです。

 open(FILE1,"file1");
 open(FILE1, "/u/jqpublic/file1");

ファイルを開くとき、アクセスモードを決めなければなりません。PERLには3つのアクセスモードがあります:読み込み、書き込み、追加です。後者の2つのモードの違いは、writeモードでは、open(outfile,">outfile")のように元のファイルを上書きして元の内容を失い、addモードで元のファイルの末尾に内容を追加し続けることです: open(appendfile, "> appendfile") という形になっています。注意:ファイルの読み込みと書き込み/追加を同時に行うことはできません。
openの戻り値は、ファイルを開く操作が成功したかどうかを判断するためのもので、成功した場合は0以外の値を返し、失敗した場合は0を返すので、次のように判断できます。
コピーコード コードは以下の通りです。

if (open(MYFILE, "myfile")) {
# here's what to do if the file opened successfully
}

ファイルを開くのに失敗したときに処理を終了させること。
コピーコード コードは以下の通りです。

unless (open (MYFILE, "file1")) {
 die ("cannot open input file file1\n");
}

また、以下のように論理演算子や演算子で表現することもできます。
コピーコード コードは以下の通りです。

 open (MYFILE, "file1") || die ("Could not open file");

ファイル操作が終了したら、close(MYFILE);でファイルを閉じます。

II. ファイルの読み込み

line =<> ;という文は、ファイルから1行のデータを読み込んで単純変数$lineに格納し、ファイルポインタを1行後ろに移動させます。これは、通常キーボード入力用の標準入力ファイルであり、開く必要はない。array = <> というステートメントは、ファイルの内容をすべて配列 @array に読み込み、ファイルの各行(キャリッジリターンを含む)を @array の 1 要素とします。

III. ファイルの書き方

という形になります。

コピーコード コードは以下の通りです。

 open(OUTFILE, ">outfile");
 print OUTFILE ("Here is an output line.\n");

注)STDOUTとSTDERRは標準出力と標準エラーファイルであり、通常は画面であり、開く必要はない。

IV. ファイルステータスの決定
1. ファイルテスト演算子
 構文は以下の通りです。-op expr, e.g.

コピーコード コードは以下の通りです。

if (-e "/path/file1") {
 print STDERR ("File file1 exists.\n");
}

ファイルテスト演算子
演算子説明
-b ブロックデバイスであるかどうか
-c キャラクタデバイスであるかどうか
-d ディレクトリであるかどうか
-e 存在する場合
-f 通常のファイルであるかどうか
-g setgidビットが設定されているかどうか
-k スティッキービットが設定されているかどうか
-l シンボリックリンクが設定されているかどうか
-o ファイルが所有されているかどうか [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...]  [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] [...]   [...] [...] [...] [...] [...] [...] [...] [...] [...] [...] コードは以下の通りです。

unless (open(INFILE, "infile")) {
 die ("Input file infile cannot be opened.\n");
}
if (-e "outfile") {
 die ("Output file outfile already exists.\n");
}
unless (open(OUTFILE, ">outfile")) {
 die ("Output file outfile cannot be opened.\n");
}

abc("a","b")です。 

abc関数は2つの引数a,bを持ちます。 
  $_[0] の値は a です。 
  1] の値は b です。
これを利用して、理解を深めることができます 

コピーコード コードは以下の通りです。

open(INFILE, "infile") && ! (-e "outfile") &&
open(OUTFILE, ">outfile") || die("Cannot open files\n");

$_[0] は関数の第1引数を示します。 
$_[1] は関数の第2引数を表します。 
などなど............。
コピーコード コードは以下の通りです。

 $var = $ARGV[0]; # First argument
 $numargs = @ARGV; # Number of arguments

++++++++++++++++++ 
Perlの式は非常に柔軟で、上記の2つの関数は等価であり、記述する他の方法がありますが、ここではより多くの例ではありませんが、実行結果は次のとおりです。 
コピーコード コードは以下の通りです。

 @ARGV = ("myfile1", "myfile2"); # actually assigned by command line arguments
 while ($line = ) {
  print ($line);
 }

前者の書き方が一般的ですが、後者はシンプルでわかりやすい書き方で、欲しい引数だけを受け取ることができ、1万個の引数を受け取る場合、$_[999]で999番目の引数を受け取り、あとは放っておけばよいという利点があります。PERLでは、カスタム関数が引数を受け取る場合、配列@_に入れ、その配列から$_[0],$_[1]が引数を受け取りに行くようになっています。

実に単純なことで、Perlのプロシージャに渡される引数はすべて@_として渡されるのです。もし2つの引数で関数を呼び出すと、関数内部では@_配列の最初の2つのメンバーである $_ [0] と $_[1] にアクセスすることができます。は普通の配列に変な名前をつけただけなので、普通の配列と同じように扱うことができます。これを知っていれば、残りの書き方は驚くことではありません。 
例えば、($first,$second)=@_;は、配列@_の2つの要素を$first,$secondに支払うことであり、@_は配列なので、$first,$secondを括弧で囲んでリスト環境を表現する。   

他にあるもの $first = shift; $second = shift; @_ の最初の要素を $first に、2番目の要素を $second に払います。
Perlの特殊変数 $&, $`,$' はパターンマッチで使用されます。

$& は、マッチの値を格納するために使用されます。
は、マッチの前のすべての文字を格納するために使用されます。
は、マッチの後のすべての文字を格納するために使用されます。

例えば

コピーコード コードは以下の通りです。

&abc("a","b")
  sub abc { 
  $first=$_[0]; 
  $second=$_[1]; 
  .... 
  }

実行結果は
コピーコード コードは以下の通りです。

  &abc("a","b") 
  sub abc { 
   $first=$_[0]; 
   $second=$_[1]; 
  print $first.$second; 
 }  

---------------------------

その他よく使われる変数 @_
はサブルーチンのプライベート変数です。もしグローバル変数 @_ があれば、このサブルーチンが呼ばれる前に格納され、サブルーチンの呼び出しが終了すると、その前の値が @_ に再代入されます。つまり、サブルーチンに引数を渡すとき、プログラムの他のサブルーチンの変数@_の値に影響を与えることを心配する必要はない。ネストされたサブルーチンが呼び出されたとき、@_の値は上記と同様です。このサブルーチンが再帰的に呼び出された場合でも、呼び出すたびに新しい @_ が取得されます。

呼び出し元のサブルーチンの前に & があり、その後に括弧がない(または引数がない)場合を除き、この呼び出し元のコンテキストから @_ が取得されます。これは通常良いアイデアではありませんが、時には便利なこともあります。

VI. パイプラインを開く

パイプは、コマンドライン(ex:ls>tempfile)と同じようにプログラムで開いて使用することもできます。例えば、open (MYPIPE, "| cat >hello"); という文でパイプを開き、MYPIPE に送られた出力は "cat >hello" というコマンドの入力となります。catコマンドは入力ファイルの内容を表示するので、この文はopen(MYPIPE, ">hello") と同じです。パイプを使ったメール送信は次のようになります。

コピーコード コードは以下の通りです。

#! /usr/bin/perl 
  $sum1 = my_sum1(1,2); 
  $sum2 = my_sum2(1,2); 
  print "sum1 = $sum1 sum2 = $sum2"; 
sub my_sum1 { 
  ($first,$second)=@_; 
  return($first+$second); 
 }
sub my_sum2 { 
 $first=$_[0]; 
 $second=$_[1]; 
 return($first+$second); 
  } 
exit;