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

Perl一括で著作権情報を追加する

2022-01-03 11:17:46

すべての入力ファイルに著作権情報がない場合は追加し、そうでない場合は何もせず、元のファイルを .bak の末尾でバックアップします。

まず始めに、私は以下の手順で行っています(試す前に必ず入力ファイルをバックアップしてください)。

#!usr/bin/perl -w
$^I = ".bak";
my %do_these;

foreach (@ARGV){
  print $_;
 $do_these{$_} = 1;
}

while(<>){
 if(/^## Copyright/){
  delete $do_these{$ARGV};
 }
}

@ARGV = sort keys %do_these;
while(<>){
 if(/^#! /){
  $_ . = "## Copyright (C) 2011 by yujianjun";
 }
 print;
}

結果 オリジナルファイルもバックアップファイルも全て空白、最悪です。(今後、プログラムをテストするときは、バックアップを取ることを忘れないでください)。
原因を分析する。

主な原因は、$^Iの使い方が間違っていることです。まず、$^Iの仕組みから見ていきましょう。

Iのデフォルト値はundefで、プログラムには影響しません。これが文字列に割り当てられると(プログラムでは ".bak" など)、プログラムはバックアップ処理を行い、その文字列をバックアップファイル名の拡張子として元のファイル名に追加します。ファイルを開くためにdiamond演算子を使用する場合、perlの操作は、まず開いたファイルの名前を拡張名を加えたファイル名に変更し、次に元のファイル名で新しいファイルを作成し、プログラムがファイルの内容を一行ずつ読み込んで何らかの変更を加えた後、新しいファイルに保存することになります。これは、ファイルの内容を変更し、古いファイルをバックアップすることと同じです。もちろん、この値がundefであれば、古いファイルはバックアップされません。

上記のプログラムでは、先頭に $^I = ".bak"; を置いていますが、その後に2つのファイル読み込み操作が続くので、この2つの操作の違いを説明します。読み込んだファイルがfile.plで、最初のwhile(<>)で元のファイルをfile.pl.bakにしたとします。すると、file.pl という名前の新しい空のファイルが作成されます。しかし、新しいファイルはプログラムの最後にしかディスクに書き込まれないので、次の2番目の読み込みファイル操作 while(<>) で、空の file.pl を file.pl.bak に変えて、最初のバックアップファイルを上書きし、新しい空のファイル file.pl を作成して、その時点で元のファイルとバックアップファイルの両方の内容が空になっていることにします。

Iの仕組みを理解すれば、このプログラムは簡単に修正することができます。

以下のように、最後のファイル読み込み操作while(<>)の前に $^I = ".bak"; を置くだけです。

#!usr/bin/perl -w

my %do_these;
@ARGV = ("sinx.pl","nvidia.pl","changeName.pl");

foreach (@ARGV){
  print $_;
 $do_these{$_} = 1;
}

while(<>){
 if(/^## Copyright/){
  delete $do_these{$ARGV};
 }
}

@ARGV = sort keys %do_these;
$^I = ".bak";
while(<>){
 if(/^#! /){
  $_ . = "## Copyright (C) 2011 by yujianjun";
 }
 print;
}

基本的にはこれで終わりですが、必要に応じて修正してください。Script Houseをもっと応援してください。