0

まず、File::Find を使用する機能がありません。

そのため、ディレクトリを調べて特定の種類のファイルを見つけるスクリプトがあります。しかし、複数のサブディレクトリの深さまで行くと、スクリプトは開始ディレクトリまで正しく終了しません。最後のディレクトリを追跡する $previousDir 変数が必要だと思うので、サブディレクトリでの作業が終わったら、そのディレクトリに戻るように言うことができます。しかし、私は成功せずに複数の場所に配置しようとしました...

ファイル構造 (太字はディレクトリ、斜体はファイル):

startingdirectory/Logs - AAADir1zzzadstatlog.299、adstatlog.tgz、ファイル

/ AAA -ファイルファイル

/ Dir1 - / Dir2config.tar.gz

/ Dir2 - 空

/ zzz -以内zzz

これが私の現在のスクリプトです:

# specify the directory where you want to start the search
my $startingDir = $ARGV[0];
my $directoryCount = 0;
my $directory = shift;
my $previousDir;
my @directories;
my $tarOutput;

# Calling the Subroutine, which searches the Directory
readDirectory($startingDir);

sub readDirectory
{
    # Open and close the startingDir
    opendir(DIR, @_[0]) or die("ERROR: Couldn't open specified directory $!");
    my @files = grep { $_ !~ /^\.{1,2}$/ } readdir DIR;
    closedir DIR;

    print "------------------------------------------------------------------------\n\n";

    foreach my $currentFile (@files)
    {   
        print "Current File: ", $currentFile, "\n\n";

        #Directory currently searching through
        print "Searching in $directory\n\n";

        my $fullPath = "$directory/$currentFile";
        print "FULL PATH: $fullPath\n\n";
        if ( -d $fullPath )
        {
            print "Found New Directory: ", $currentFile, "\n\n";
            push (@directories, $currentFile);
            $directoryCount++;
            print "Current number = $directoryCount\n\n";
            print "Directories: @directories \n\n";
            $previousDir = $directory;
            $directory = $fullPath;
            # The Subroutine is calling hisself with the new parameters
            readDirectory($directory);
        }

        elsif ( $currentFile =~ /\.tar.gz$/i || $currentFile =~ /\.tar$/i || $currentFile =~ /\.tgz$/i)
        {
            print "File: ", $currentFile, "\n\n";
            my $tarOutput = `tar -tvzf $currentFile`;
            print $tarOutput, "\n";
            $previousDir = $directory;
        }

        print "PREVIOUSDIR: $previousDir\n\n";

        print "-----------------------------------------------------------------------\n\n";

        $directory = $previousDir;
    }   
}

そして出力:(下にスクロールして問題の始まりを確認してください)

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

Current File: AAA

Searching in /home/gackerma/Logs

FULL PATH: /home/gackerma/Logs/AAA

Found New Directory: AAA

Current number = 1

Directories: AAA

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

Current File: filefile

Searching in /home/gackerma/Logs/AAA

FULL PATH: /home/gackerma/Logs/AAA/filefile

PREVIOUSDIR: /home/gackerma/Logs

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

 PREVIOUSDIR: /home/gackerma/Logs

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

Current File: Dir1

Searching in /home/gackerma/Logs

FULL PATH: /home/gackerma/Logs/Dir1

Found New Directory: Dir1

Current number = 2

Directories: AAA Dir1

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

Current File: DIR2

Searching in /home/gackerma/Logs/Dir1

FULL PATH: /home/gackerma/Logs/Dir1/DIR2

Found New Directory: DIR2

Current number = 3

Directories: AAA Dir1 DIR2

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

PREVIOUSDIR: /home/gackerma/Logs/Dir1

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

Current File: configs.tar.gz

Searching in /home/gackerma/Logs/Dir1

FULL PATH: /home/gackerma/Logs/Dir1/configs.tar.gz

PREVIOUSDIR: /home/gackerma/Logs/Dir1

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

PREVIOUSDIR: /home/gackerma/Logs/Dir1  ***THIS IS WHERE THE ISSUE STARTS - 
                                          PREVIOUSDIR SHOULD BE /Logs!!***

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

Current File: file

Searching in /home/gackerma/Logs/Dir1

FULL PATH: /home/gackerma/Logs/Dir1/file

PREVIOUSDIR: /home/gackerma/Logs/Dir1

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

Current File: adstatlog.299

Searching in /home/gackerma/Logs/Dir1

FULL PATH: /home/gackerma/Logs/Dir1/adstatlog.299

PREVIOUSDIR: /home/gackerma/Logs/Dir1

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

Current File: zzz

Searching in /home/gackerma/Logs/Dir1

FULL PATH: /home/gackerma/Logs/Dir1/zzz

PREVIOUSDIR: /home/gackerma/Logs/Dir1

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

Current File: adstatlog.tgz

Searching in /home/gackerma/Logs/Dir1

FULL PATH: /home/gackerma/Logs/Dir1/adstatlog.tgz

PREVIOUSDIR: /home/gackerma/Logs/Dir1

------------------------------------------------------------------
4

3 に答える 3

0

あなたのプログラムには多くの問題があります。主なエラーは、使用しているグローバル変数が多すぎて、現在処理中のディレクトリとの同期を手動で維持しようとしていることです。

ここにリストがあります

  • あなたが書くすべてのプログラムuse strictに対して常にuse warnings

  • warningsopendir(DIR, $_[0])代わりに書くべきだとあなたに言ったでしょうopendir(DIR, @_[0])

  • ディレクトリ内のすべてのエントリの後に設定$directoryしています。$previousDirただし$previousDir、現在のエントリが別のディレクトリである場合にのみ設定されているため、通常のファイルの後、保存されていなくても値が復元されます。

  • $directoryグローバル変数で指定されたディレクトリを読み取るべきか、サブルーチンに渡されたパラメータで指定されたディレクトリを読み取るべきかについて混乱しています。

これを行う最も簡単な方法は、サブルーチン パラメータのみを使用して現在のディレクトリを指定し、グローバル変数を忘れることです。これは、あなたが意図していることを行うプログラムです

use strict;
use warnings;

process_dir($ARGV[0]);

sub process_dir {

  my ($dir) = @_;

  opendir my $dh, $dir or die $!;
  my @entries = grep { not /^\.\.?$/ } readdir $dh;
  closedir $dh;

  for my $entry (@entries) {
    my $fullname = "$dir/$entry";
    if (-d $fullname) {
      process_dir($fullname);
    }
    elsif ($entry=~ /(?:\.tar|\.tgz|\.tar\.gz)$/i)
      print "File: ", $fullname, "\n\n";
      print `tar -tvzf $fullname`;
    }
  }
}
于 2013-05-21T14:42:00.030 に答える