ASH | サーバ | セキュリティ | Linux | FreeBSD | DB | Web | CGI | Perl | Java | XML | プログラム | ネットワーク | 標準 | Tips集

Perlサンプルプログラム集

 Perlのサンプルプログラム集です。 実際に使っているPerlスクリプトですが、プログラムソースとして公開するには、汎用性に欠けるものを集めてあります。 用途が限定されていますので、パラメータの指定は、スクリプトの先頭で変数に代入して使うものもあります。
 このようなサンプルを流用すると、必要なスクリプトは、1日から2日で作成することができます。
 ASHのホームページで公開しているスクリプトの著作権はASHにあります。 スクリプトの利用や改造は、非商用、商用にかかわらず自由です。 ただし、利用される場合は、ASHへのリンク、ASHに対するカンパ、ASHに対する仕事の依頼などをお願いします。 ASHではスクリプトの作成も行っています。

連続年月生成スクリプト

 日次処理のテストのために、そのパラメータ用に、連続した日付を生成するスクリプトです。 評価用のログデータの自動生成などにも使えます。
 スクリプトの先頭の変数に開始年月と終了年月を設定することで、連続した年月日を自動生成します。 このスクリプトは、1991年から、2099年までの範囲で使えます。
 出力書式などを変更したい場合は、スクリプトを修正してください。

gen_date.pl
#!/usr/local/bin/perl
#
#  Date Generator
#

# 開始年月の設定
$yy_s = 1999; # start year(1997-2003)
$mm_s = 04;   # start month(01-12)
$dd_s = 01;   # start day(01-31)

# 終了年月の設定
$yy_e = 2005; # end year(1997-2003)
$mm_e = 03;   # end month(01-12)
$dd_e = 31;   # end day(01-31)

&gen_date($yy_s,$mm_s,$dd_s,$yy_e,$mm_e,$dd_e);


# 日付の連続生成
sub gen_date {
  my($yy_s,$mm_s,$dd_s,$yy_e,$mm_e,$dd_e) = @_;

  $yy = $yy_s;  # year(1997-2003)
  $mm = $mm_s;  # month(01-12)
  $dd = $dd_s;  # day(01-31)

  while (1) {
    # 年月日表示
    printf ("%04d%02d%02d\n", $yy, $mm, $dd);

    # 終了日判断
    if ($yy >= $yy_e) {
      if ($mm >= $mm_e) {
        if ($dd >= $dd_e) {
          last;
        }
      }
    }

    # 翌日計算
    $dd++;
    if ($mm == 2) {
      if ($dd > 28) {
        if ($dd > 29) {
          $mm++;
          $dd = 1;
        } else {
          if ($yy % 4) { # うるう年以外
            $mm++;
            $dd = 1;
          }
        }
      }
    } elsif (($mm == 4) || ($mm == 6) || ($mm == 9) || ($mm == 11)) {
      if ($dd > 30) {
        $mm++;
        $dd = 1;
      }
    } else {
      if ($dd > 31) {
        $mm++;
        $dd = 1;
      }
      if ($mm > 12) {
        $yy++;
        $mm = 1;
      }
    }
  }
}

関連オブジェクトの自動削除スクリプト

 Cでプログラミングする場合は、メイクファイルを使ってメイクします。 メイクファイルでは、ソースとオブジェクトの関連を定義することで、変更のあったプログラムだけがコンパイルされます。 しかし、ヘッダファイルをインクルードしている場合は、ヘッダとオブジェクトの関連を定義しなければならないのと、ヘッダのコメントを修正しても、関連するプログラムがコンパイルされたりしてしまいます。
 そこで、ヘッダとオブジェクトの関連は定義せずに、メイクファイルは推論規則により、自動メイクするようにします。 これにより、メイクファイルの保守や、無駄なコンパイルを減らすことが出来ます。 ただし、ヘッダを変更してもコンパイルされないため、ヘッダ名を指定すると、そのヘッダを利用しているソースのオブジェクトを削除するスクリプトを利用します。
 このスクリプトを利用する場合は、ディレクトリ配下に、src,inc,objというディレクトリが存在する必要があります。

del_obj.pl
#!/usr/local/bin/perl
#
# 関連オブジェクトファイル削除コマンド
#   src配下の*.c,*.pcのファイルを検索
#   include文で指定したヘッダを利用しているファイルを抽出
#   obj配下の関連するオブジェクトファイルを削除
#
# ディレクトリ構成
#   $base_dir
#    ├src/ ソース格納用
#    ├inc/ ヘッダ格納用
#    └obj/ オブジェクト格納用
#

&init(); # 初期設定
&main(); # メイン処理
exit(0);

# 使用方法の表示
sub usage {
  printf("Usage: %s [-d base_dir] inc_files\n", $prog_name);
  exit(-1);
}

# 初期設定
sub init {
  $base_dir = '.';  # デフォルトベースディレクトリ
  $src_dir = 'src'; # デフォルトソースディレクトリ
  $obj_dir = 'obj'; # デフォルトオブジェクトディレクトリ
}

# コマンドオプションの取得
sub get_opt {
  # デフォルトパラメータの設定
  $prog_name = $0;

  # オプションの解析
  while ($#ARGV >= 0) {
    if ($ARGV[0] eq "-x") { # デバッグモード
      $dbg = 1;
    } elsif ($ARGV[0] eq "-d") { # ベースディレクトリの変更
      shift(@ARGV);
      $base_dir = $ARGV[0];
    } elsif ($ARGV[0] =~ /^-/) { # 使用方法の表示
      &usage();
    } else {
      last;
    }
    shift(@ARGV);
  }

  @incs = @ARGV; # ヘッダ名の指定(複数可)
  if (@incs == 0) {&usage();}
}

# メイン処理
sub main {
  my (@files, $file);
  my ($buf, $inc, $obj);

  &get_opt(); # コマンドオプションの取得

  # ディレクトリの初期設定
  $src_dir = "$base_dir/$src_dir";
  $obj_dir = "$base_dir/$obj_dir";

  # 設定値の表示
  if ($dbg) {
    print "base_dir = $base_dir\n";
    print "src_dir = $src_dir\n";
    print "obj_dir = $obj_dir\n";
    print "incs = @incs\n\n";
  }

  # ファイル一覧の取得
  if (!opendir(DIR, $src_dir)) {
    printf("Directory %s open error.\n",$src_dir);
    exit(1);
  }
  @files = readdir(DIR);
  closedir(DIR);

  # ファイル処理
  L_FILE: foreach $file (@files) {
    if ($file !~ /(.*)(\.pc|\.c)$/)  {next;}

    $base = $1;
    $path = "$src_dir/$file";
    if ($dbg) {print "path = $path\n";}

    $file_open = "<$path";
    if (!open(FILE_IN, $file_open)) {
      printf("File %s open error.\n",$path);
      exit(1);
    }

    # レコード処理
    L_REC: while(<FILE_IN>) {
      chomp($buf = $_);
      # include文以外は次の行へ
      if ($buf !~ /^#include/) {next;}
      if ($dbg) {print "buf = $buf\n";}

      # ヘッダチェック処理
      L_INC: foreach $inc (@incs) {
        if ($buf =~ /$inc/) { # 対象となるヘッダを利用
          $obj = "$obj_dir/$base.o";

          # 関連オブジェクトファイルの削除
          print "rm -f $obj\n";
          system("/bin/rm -f $obj");
          next L_FILE;
        }
      }
    }

    close(FILE_IN);
  }
}


Copyright (C)1995-2002 ASH multimedia lab.
mail : info@ash.jp