浏览目录的最佳方式是什么?

发布于 2024-08-21 16:26:32 字数 1304 浏览 6 评论 0原文

下面的两个例子都可以吗,还是第二个例子风格不好?

情况 1:留在顶层目录并使用 catdir 访问子目录

#!/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";

情况 2:更改为子目录并在退出前恢复顶层目录

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";

Are both of the examples below OK, or is the second one bad style?

Case 1: Stay in top directory and use catdir to access subdirectories

#!/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";

Case 2: Change to subdirectories and restore top directory before exit

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";

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

七禾 2024-08-28 16:26:32

您的问题是您是否应该更改到正在浏览的目录或保留在顶级目录中。

答案是:这取决于。

例如,考虑文件::查找。默认行为确实是更改目录。但是,该模块还提供了 no_chdir 选项如果这是不可取的。

就您的示例而言,File::Find 可能不合适,因为您不想递归遍历所有子目录,而只想递归一个子目录。这是基于 File::Slurp::read_dir 的脚本变体。

#!/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";

Your question is whether you should change to the directories you are going through or stay in the top level directory.

The answer is: It depends.

For example, consider File::Find. The default behavior is to indeed change directories. However, the module also provides a no_chdir option in case that is not desirable.

In the case of your examples, File::Find is probably not appropriate because you do not want to recurse through all subdirectories but only one. Here is a File::Slurp::read_dir based variation on your script.

#!/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";
少跟Wǒ拽 2024-08-28 16:26:32

对于您的示例,最好更改为子目录,并且不要在最后更改回原始目录。这是因为每个进程都有自己的“当前目录”,因此您的 perl 脚本正在更改其自己的当前目录这一事实并不意味着 shell 的当前目录已更改;相反,它会更改 shell 的当前目录。保持不变。

如果这是一个更大脚本的一部分,那就会有所不同;我的一般偏好是不更改目录,只是为了减少对脚本中任何点当前目录的混淆。

For your example, it's best to change to subdirectories, and don't bother changing back to the original directory at the end. That's because each process has its own "current directory", so the fact that your perl script is changing it's own current directory does not mean that the shell's current directory is changed; that stays unaltered.

If this was part of a larger script it would be different; my general preference then would be not to change directory, just to reduce confusion over what the current directory is at any point in the script.

心的憧憬 2024-08-28 16:26:32

使用 File::Find,正如您已经建议的那样:)

使用模块来解决这样的问题几乎总是比自己推出更好,除非您真的想了解步行目录...

Use File::Find, as you already proposed :)

It's almost always better to use a module for solved problems like this than to roll your own, unless you really want to learn about walking dirs...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文