スタッフブログ

STAFF BLOG

アプリ開発日誌

2016.08.24

Perlでファイルを自動的にコピーしてみる

はじめに

プログラマの小林です。
本日は、ファイルを自動的に目的のディレクトリに展開する処理について
簡単に説明したいと思います。

最近Androidの案件で、リソースファイルを
以下のようなディレクトリ構成でいただくことがありました。
resource_parts
|- drawable-hdpi
|- drawable-xhdpi
|- drawable-xxhdpi
|- drawable-xxxhdpi
resource_background
|- drawable-hdpi
|- drawable-xhdpi
|- drawable-xxhdpi
|- drawable-xxxhdpi
これだけの数なら手動でも問題はないのですが、
実際は「Aの画面の画像」「Bの画面の画像」などのように
渡されます。これだと種類が多くなってきた時に
コピーのミスや不足が発生してしまいます。
なので、スクリプトファイルで自動的にファイルのコピーをするようにしました。

今回の実行環境は
・Mac OS X 10.11
・Perl 5.18
となっています。

 

Perl

今回使用した言語はPerlです。
Perlは言語の文法レベルで正規表現を使用できる機能が含まれています。
これによって、ディレクトリとファイル名のマッチング処理を簡単に記述することができます。

 

スクリプトファイル

それではファイルの内容を見ていきましょう。
ファイルの名前はcpy_files.plとしておきます。

#!/usr/bin/perl
use strict;
use warnings;

use Cwd;

use constant {
  # 展開先のリソースフォルダの絶対パス
  DEPLOY_TARGET_DIRECTORY => "/path/to/resource/folder/res",
  # 展開先にあるdrawableリソースフォルダ名
  DEPLOY_TARGET_PATTERN => "drawable-[x]*hdpi",
};

######## メイン処理
my $currentDir = Cwd::getcwd();
# ファイルをプロジェクトディレクトリにコピー
deployFiles($currentDir);
######## メイン処理 終わり

まずはメイン処理です。
ソース内でのディレクトリ名やパターンの記述は
このように定数にまとめておいたほうがいいです。
deployFilesで実際の処理を行っています。

 

ディレクトリの走査

次にディレクトリを走査する部分を見ていきましょう。

sub deployFiles {
  my $currentDir = shift;
  my @list = ();

  #カレントディレクトリの一覧を取得
  opendir(DIR, $currentDir) or die("ディレクトリを取得できませんでした:$currentDir ($!)");
  @list = readdir(DIR);
  closedir(DIR);

  foreach my $dir (sort @list) {
    # "."と".."に対しては処理しない
    next if($dir =~ /^\.{1,2}$/);
    #ディレクトリのみにマッチ
    if(-d "$currentDir/$dir") {
      # パターンの後に自分と同じ名前のディレクトリがあるかどうか検査する
      if(-d DEPLOY_TARGET_DIRECTORY."/$dir") {
        copyFiles($currentDir, $dir);
      }

      # 自分の下のディレクトリもプロジェクトに展開する
      deployFiles("$currentDir/$dir");
    }
  }
}

deployFilesの処理内容です。ここではディレクトリを走査して、
ターゲットのディレクトリ(drawable-xhdpiなど)と同じ名前のディレクトリかどうか
比較をしています。
一致したディレクトリがあった場合、その中にあるファイルを
copyFilesサブルーチンで全てコピーします。
また、再帰的に自分の下にあるディレクトリも走査します。

 

ファイルの展開

次にファイルをコピーする部分を見ていきましょう。

sub copyFiles {
  my $currentDir = $_[0];
  my $targetDir = $_[1];
  my @list = ();
  # ディレクトリ内のディレクトリ・ファイルを取得
  opendir(DIR, "$currentDir/$targetDir") or die("ディレクトリを取得できませんでした:$currentDir/$targetDir ($!)");
  @list = readdir(DIR);
  closedir(DIR);

  foreach my $file (sort @list) {
    # "."と".."と隠しファイルに対しては処理しない
    next if($file =~ /^\.{1,2}.*$/);
    #ファイルのみにマッチ
    if(-f "$currentDir/$targetDir/$file") {
      copyFile($currentDir, $targetDir, $file);
    }
  }
}

sub copyFile {
  my $currentDir = $_[0];
  my $targetDir = $_[1];
  my $file = $_[2];

  my $cur = "$currentDir/$targetDir/$file";
  my $tar = DEPLOY_TARGET_DIRECTORY."/$targetDir/$file";
  open(OLD, "$cur");
  open(NEW, ">", "$tar");
  while(<OLD>) {
    print NEW $_;
  }
  close(OLD);
  close(NEW);
}

適切な名前のディレクトリを発見したので、その中にあるファイルを全てコピーします。
ファイルが存在しない場合、新規に作成され、既に存在している場合は
コピー元のファイルで上書きされます。

以上が書き終わったら、ターミナルからスクリプトのあるディレクトリに移動して
$perl cpy_files.pl
で実行できます。

 

まとめ

以上がPerlによるファイルコピー処理の自動化になります。
このように、かなり少ない行数でファイル名のマッチングとコピーが
書けるようになっています。
皆さんも仕事で「手動でやると大変だな」と思うことがあれば、
スクリプトでどんどん自動化・効率化していきましょう!

 

BACK

お問合せ

イーディーエーに興味をお持ちいただいて
ありがとうございます!
スマホアプリに関するご相談、
お見積りや弊社へのご質問など、
お気軽にお問い合わせください。
担当者より折り返しご連絡させていただきます。

    お名前必須
    会社名
    メールアドレス必須
    電話番号必須
    お問合わせ種別必須
    お問合わせ内容必須

    アンケートにご協力ください。
    弊社サイトへはどのようにしてアクセスされましたか?

    個人情報のお取扱いに関する同意事項

    1.事業者の氏名又は名称

    株式会社イーディーエー

    2.個人情報保護管理者の氏名又は職名、所属及び連絡先

    個人情報保護管理者 小宮 保人
    Mail:[email protected]

    3.取得した個人情報の利用目的

    当フォームで取得した個人情報は、お問い合わせに関する回答のために利用し、目的外利用はいたしません。

    4.弊社が取得した個人情報の第三者への委託、提供について

    弊社は、ご本人に関する情報をご本人の同意なしに第三者に委託または提供することはありません。

    5.個人情報保護のための安全管理

    弊社は、ご本人の個人情報を保護するための規程類を定め、従業者全員に周知・徹底と啓発・教育を図るとともに、その遵守状況の監査を定期的に実施いたします。
    また、ご本人の個人情報を保護するために必要な安全管理措置の維持・向上に努めてまいります。

    6.個人情報の開示・訂正・利用停止等の手続

    ご本人が、弊社が保有するご自身の個人情報の、利用目的の通知、開示、内容の訂正、追加又は削除、利用の停止、消去及び第三者への提供の停止を求める場合には、下記に連絡を頂くことで、対応致します。

    株式会社イーディーエー 個人情報お問合せ窓口
    〒106-0032 東京都港区六本木7丁目14番23 ラウンドクロス六本木4F
    TEL:03-5422-7524 FAX:03-5422-7534
    Mail:[email protected]

    7.ご提供いただく情報の任意性

    個人情報のご提供は任意ですが、同意を頂けない場合には、第3項にあります利用目的が達成できない事をご了承いただくこととなります。

    8.弊社Webサイトの運営について

    弊社サイトでは、ご本人が弊社Webサイトを再度訪問されたときなどに、より便利に閲覧して頂けるよう「クッキー(Cookie)」という技術を使用することがあります。これは、ご本人のコンピュータが弊社Webサイトのどのページに訪れたかを記録しますが、ご本人が弊社Webサイトにおいてご自身の個人情報を入力されない限りご本人ご自身を特定、識別することはできません。
    クッキーの使用を希望されない場合は、ご本人のブラウザの設定を変更することにより、クッキーの使用を拒否することができます。その場合、一部または全部のサービスがご利用できなくなることがあります。