Perlでtar.gzファイルを再帰的に展開する方法

Perlでtar.gzファイルを再帰的に展開する方法

Posted at September 18,2013 12:55 AM
Tag:[Perl]

Perlでtar.gzファイル(tgzファイル)を再帰的に展開する方法を紹介します。

1.条件

  • 起動時のパラメータでトップディレクトリを指定
  • トップディレクトリ配下のtar.gzファイルを展開
  • 展開した中にtar.gzファイルが存在する場合はさらに展開

Perl5.8の環境です。

2.サンプルコード

拙いコードですが、1項の条件を満たすサンプルを作ってみました。

#!/usr/bin/perl
 
use strict;
use File::Find;
 
our @list;
 
my $dir = shift(@ARGV);
find( \&execute, $dir );
 
sub execute {
    if (/\.tgz|\.tar\.gz/) {
        my $file = "$File::Find::name";
        my @grep = grep /$file/, @list if @list;
        if ( !@grep ) {
            push @list, $file;
            my $result = `tar -zxvf $file`;
            find( \&execute, $dir );
        }
    }
}

File::Findはディレクトリを変更しながら、すべてのファイルを処理するモジュールです。

use File::Find;

File::Find::find()は、第1パラメータに設定した関数で第2パラメータに指定したディレクトリまたはファイル(配列も可)を処理します。この1行で、第2パラメータに指定したディレクトリ配下のディレクトリやファイルをすべて探索してくれます。

find( \&execute, $dir );

execute()メソッドでは、ファイルの拡張子が「.tgz」または「.tar.gz」の場合のみ処理を継続するようにします。

    if (/\.tgz$|\.tar\.gz/) {
        :
    }

$File::Find::nameでファイル名(フルパス)を取得します。

        my $file = "$File::Find::name";

一度展開したアーカイブを展開しないよう、リストを検索します。

        my @grep = grep /$file/, @list if @list;

リストになければ現在のファイルをリストに追加し、tarコマンドを実行します。

        if ( !@grep ) {
            push @list, $file;
            my $result = `tar -zxvf $file`;

展開したらfind()を再帰的に呼び出します(呼び出さないと展開したディレクトリを探索しないのでこのようにしています)。

            find( \&execute, $dir );

再帰呼び出しの第2パラメータは起動時のディレクトリを再指定していますが、本来は展開したアーカイブに含まれるディレクトリに絞った方がいいと思います。

Archive::Extractとか、もっといい方法があればどこかでつぶやいてください。

関連記事
トラックバックURL


コメントする
greeting

*必須

*必須(非表示)


ご質問のコメントの回答については、内容あるいは多忙の場合、1週間以上かかる場合があります。また、すべてのご質問にはお答えできない可能性があります。予めご了承ください。

太字イタリックアンダーラインハイパーリンク引用
[サインインしない場合はここにCAPTCHAを表示します]

コメント投稿後にScript Errorや500エラーが表示された場合は、すぐに再送信せず、ブラウザの「戻る」ボタンで一旦エントリーのページに戻り(プレビュー画面で投稿した場合は、投稿内容をマウスコピーしてからエントリーのページに戻り)、ブラウザをリロードして投稿コメントが反映されていることを確認してください。

コメント欄に(X)HTMLタグやMTタグを記述される場合、「<」は「&lt;」、「>」は「&gt;」と入力してください。例えば「<$MTBlogURL$>」は「&lt;$MTBlogURL$&gt;」となります(全て半角文字)