2 Stimmen

Wie kann man sich am besten durch Verzeichnisse bewegen?

Sind beide Beispiele in Ordnung, oder ist das zweite Beispiel ein schlechter Stil?

Fall 1: Bleiben Sie im Hauptverzeichnis und verwenden Sie catdir, um auf Unterverzeichnisse zuzugreifen

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

my $dir = 'my_dir_with_subdir';
my ( $count, $dh );

use File::Spec::Functions;
$count = 0;

opendir $dh, $dir or die $!;
while ( defined( my $file = readdir $dh ) ) {
    next if $file =~ /^\.{1,2}$/;
    my $sub_dir = catdir $dir, $file;
    if ( -d $sub_dir ) {
        opendir my $dh, $sub_dir or die $!;
        while ( defined( my $file = readdir $dh ) ) {
            next if $file =~ /^\.{1,2}$/;
            $count++;
        }
        closedir $dh or die $!;
    }
    else {
        $count++;
    }
}

closedir $dh or die $!;
print "$count\n";

Fall 2: Wechsel in Unterverzeichnisse und Wiederherstellung des Hauptverzeichnisses vor dem Beenden

use Cwd;
my $old = cwd;
$count = 0;
opendir $dh, $dir or die $!;
chdir $dir or die $!;
while ( defined( my $file = readdir $dh ) ) {
    next if $file =~ /^\.{1,2}$/;
    if ( -d $file ) {
        opendir my $dh, $file or die $!;
        chdir $file or die $!;
        while ( defined( my $file = readdir $dh ) ) {
            next if $file =~ /^\.{1,2}$/;
            $count++;
        }
        closedir $dh or die $!;
        chdir $dir;
    }
    else {
        $count++;
    }
}
closedir $dh or die $!;
chdir $old or die $!;
print "$count\n";

2voto

Sinan Ünür Punkte 114993

Ihre Frage ist, ob Sie in die Verzeichnisse wechseln sollten, durch die Sie gehen, oder im übergeordneten Verzeichnis bleiben sollten.

Die Antwort lautet: Das kommt darauf an.

Zum Beispiel Datei::Finden . Standardmäßig werden die Verzeichnisse tatsächlich gewechselt. Das Modul bietet jedoch auch eine no_chdir für den Fall, dass dies nicht erwünscht ist.

Im Falle Ihrer Beispiele, File::Find ist wahrscheinlich nicht geeignet, weil Sie nicht alle Unterverzeichnisse durchsuchen wollen, sondern nur eines. Hier ist ein Datei::Slurp::read_dir auf der Grundlage Ihres Drehbuchs.

#!/usr/bin/perl

use strict; use warnings;

use File::Slurp;
use File::Spec::Functions qw( catfile );

my ($dir) = @ARGV;

my $contents = read_dir $dir;
my $count = 0;

for my $entry ( @$contents ) {
    my $path = catfile $dir, $entry;
    -f $path and ++ $count and next;
    -d _ and $count += () = read_dir $path;
}

print "$count\n";

1voto

dave4420 Punkte 45576

Für Ihr Beispiel ist es am besten, in Unterverzeichnisse zu wechseln und sich nicht die Mühe zu machen, am Ende wieder in das ursprüngliche Verzeichnis zu wechseln. Das liegt daran, dass jeder Prozess sein eigenes "aktuelles Verzeichnis" hat, so dass die Tatsache, dass Ihr Perl-Skript sein eigenes aktuelles Verzeichnis ändert, nicht bedeutet, dass das aktuelle Verzeichnis der Shell geändert wird; das bleibt unverändert.

Wenn dies Teil eines größeren Skripts wäre, wäre es anders; meine allgemeine Präferenz wäre dann, das Verzeichnis nicht zu wechseln, nur um Verwirrung darüber zu vermeiden, welches das aktuelle Verzeichnis an irgendeinem Punkt im Skript ist.

0voto

Powertieke Punkte 2268

Verwenden Sie File::Find, wie Sie bereits vorgeschlagen haben :)

Es ist fast immer besser, ein Modul für gelöste Probleme wie dieses zu verwenden, als ein eigenes zu entwickeln, es sei denn, Sie wollen wirklich etwas über Walking Dirs lernen...

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X