关于 opendir 和 readdir 的 Perl 程序帮助

发布于 2024-10-05 01:27:00 字数 375 浏览 4 评论 0原文

所以我有一个程序想要清理一些文本文件。该程序要求用户输入包含这些文本文件的目录的完整路径。从那里我想读取目录中的文件,将它们打印到一个新文件(由用户指定),然后按照我需要的方式清理它们。我已经编写了清理文本文件的脚本。

我向用户询问要使用的目录:

chomp ($user_supplied_directory = <STDIN>); 
opendir (DIR, $user_supplied_directory);

然后我需要读取该目录。

my @dir = readdir DIR;

foreach (@dir) {

现在我迷路了。

有什么帮助吗?

So I have a program that I want to clean some text files. The program asks for the user to enter the full pathway of a directory containing these text files. From there I want to read the files in the directory, print them to a new file (that is specified by the user), and then clean them in the way I need. I have already written the script to clean the text files.

I ask the user for the directory to use:

chomp ($user_supplied_directory = <STDIN>); 
opendir (DIR, $user_supplied_directory);

Then I need to read the directory.

my @dir = readdir DIR;

foreach (@dir) {

Now I am lost.

Any help please?

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

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

发布评论

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

评论(4

万水千山粽是情ミ 2024-10-12 01:27:01

我不确定你想要什么。所以,我做了一些假设:

  • 当你说清理文本文件时,你的意思是删除文本文件
  • 你想要写入的文件的名称是由一个模式组成的。

所以,如果我是对的,请尝试这样的事情:

chomp ($user_supplied_directory = <STDIN>);

opendir (DIR, $user_supplied_directory);
my @dir = readdir DIR;

foreach (@dir) {
    next if (($_ eq '.') || ($_ eq '..'));

    # Reads the content of the original file
    open FILE, $_;
    $contents = <FILE>;
    close FILE;

    # Here you supply the new filename
    $new_filename = $_ . ".new";

    # Writes the content to the new file
    open FILE, '>'.$new_filename;
    print FILE $content;
    close FILE;

    # Deletes the old file
    unlink $_;
}

I'm not certain of what do you want. So, I made some assumptions:

  • When you say clean the text file, you meant delete the text file
  • The names of the files you want to write into are formed by a pattern.

So, if I'm right, try something like this:

chomp ($user_supplied_directory = <STDIN>);

opendir (DIR, $user_supplied_directory);
my @dir = readdir DIR;

foreach (@dir) {
    next if (($_ eq '.') || ($_ eq '..'));

    # Reads the content of the original file
    open FILE, $_;
    $contents = <FILE>;
    close FILE;

    # Here you supply the new filename
    $new_filename = $_ . ".new";

    # Writes the content to the new file
    open FILE, '>'.$new_filename;
    print FILE $content;
    close FILE;

    # Deletes the old file
    unlink $_;
}
没︽人懂的悲伤 2024-10-12 01:27:01

我建议您切换到 File::Find。一开始可能会有点挑战,但它功能强大且跨平台。

但是,要回答您的问题,请尝试以下操作:

my @files = readdir DIR;
foreach $file (@files) {
   foo($user_supplied_directory/$file);
}

其中“foo”是您需要对文件执行的操作。一些注释可能会有所帮助:

  • 使用“@dir”作为文件数组有点误导
  • 需要将文件夹名称添加到文件名前面才能获取正确的文件
  • 使用grep可能会很方便扔掉不需要的文件和子文件夹,尤其是“..”

I would suggest that you switch to File::Find. It can be a bit of a challenge in the beginning but it is powerful and cross-platform.

But, to answer your question, try something like:

my @files = readdir DIR;
foreach $file (@files) {
   foo($user_supplied_directory/$file);
}

where "foo" is whatever you need to do to the files. A few notes might help:

  • using "@dir" as the array of files was a bit misleading
  • the folder name needs to be prepended to the file name to get the right file
  • it might be convenient to use grep to throw out unwanted files and subfolders, especially ".."
眼睛会笑 2024-10-12 01:27:01

我今天写了一些使用 readdir 的东西。也许你可以从中学到一些东西。这只是一个(稍微)更大的程序的一部分:

our @Perls = ();

{
    my $perl_rx = qr { ^ perl [\d.] + $ }x;
    for my $dir (split(/:/, $ENV{PATH})) {
        ### scanning: $dir
        my $relative = ($dir =~ m{^/});
        my $dirpath = $relative ? $dir : "$cwd/$dir";
        unless (chdir($dirpath)) {
            warn "can't cd to $dirpath: $!\n";
            next;
        }
        opendir(my $dot, ".") || next;
        while ($_ = readdir($dot)) {
            next unless /$perl_rx/o;
            ### considering: $_
            next unless -f;
            next unless -x _;
            ### saving: $_
            push @Perls, "$dir/$_";
        }
    }
}

{
    my $two_dots = qr{ [.] .* [.] }x;
    if (grep /$two_dots/, @Perls) {
        @Perls = grep /$two_dots/, @Perls;
    }
}

{
    my (%seen, $dev, $ino);
    @Perls = grep {
        ($dev, $ino) = stat $_;
        ! $seen{$dev, $ino}++;
    } @Perls;
}

关键是 push(@Perls, "$dir/$_"):由 readdir 读取的文件名是基名仅有的;它们不是完整路径名。

I wrote something today that used readdir. Maybe you can learn something from it. This is just a part of a (somewhat) larger program:

our @Perls = ();

{
    my $perl_rx = qr { ^ perl [\d.] + $ }x;
    for my $dir (split(/:/, $ENV{PATH})) {
        ### scanning: $dir
        my $relative = ($dir =~ m{^/});
        my $dirpath = $relative ? $dir : "$cwd/$dir";
        unless (chdir($dirpath)) {
            warn "can't cd to $dirpath: $!\n";
            next;
        }
        opendir(my $dot, ".") || next;
        while ($_ = readdir($dot)) {
            next unless /$perl_rx/o;
            ### considering: $_
            next unless -f;
            next unless -x _;
            ### saving: $_
            push @Perls, "$dir/$_";
        }
    }
}

{
    my $two_dots = qr{ [.] .* [.] }x;
    if (grep /$two_dots/, @Perls) {
        @Perls = grep /$two_dots/, @Perls;
    }
}

{
    my (%seen, $dev, $ino);
    @Perls = grep {
        ($dev, $ino) = stat $_;
        ! $seen{$dev, $ino}++;
    } @Perls;
}

The crux is push(@Perls, "$dir/$_"): filenames read by readdir are basenames only; they are not full pathnames.

洒一地阳光 2024-10-12 01:27:01

您可以执行以下操作,允许用户提供自己的目录,或者如果用户未指定目录,则默认为指定位置。

该示例展示了opendirreaddir的使用,将目录中的所有文件存储在@files数组中,并且仅存储以'结尾的文件@keys 数组中的 .txt'。 while 循环确保文件的完整路径存储在数组中。

这假设您的“文本文件”以“.txt”后缀结尾。我希望这会有所帮助,因为我不太确定“清理文件”是什么意思。

use feature ':5.24';
use File::Copy;

my $dir = shift || "/some/default/directory";

opendir(my $dh, $dir) || die "Can't open $dir: $!";

while ( readdir $dh ) {
    push( @files, "$dir/$_");
}

# store ".txt" files in new array
foreach $file ( @files ) {
    push( @keys, $file ) if $file =~ /(\S+\.txt\z)/g;
}

# Move files to new location, even if it's across different devices
for ( @keys ) {
    move $_, "/some/other/directory/"; || die "Couldn't move files: $!\n";
}

有关详细信息,请参阅 File::Copy 的 perldoc

You can do the following, which allows the user to supply their own directory or, if no directory is specified by the user, it defaults to a designated location.

The example shows the use of opendir, readdir, stores all files in the directory in the @files array, and only files that end with '.txt' in the @keys array. The while loop ensures that the full path to the files are stored in the arrays.

This assumes that your "text files" end with the ".txt" suffix. I hope that helps, as I'm not quite sure what's meant by "cleaning the files".

use feature ':5.24';
use File::Copy;

my $dir = shift || "/some/default/directory";

opendir(my $dh, $dir) || die "Can't open $dir: $!";

while ( readdir $dh ) {
    push( @files, "$dir/$_");
}

# store ".txt" files in new array
foreach $file ( @files ) {
    push( @keys, $file ) if $file =~ /(\S+\.txt\z)/g;
}

# Move files to new location, even if it's across different devices
for ( @keys ) {
    move $_, "/some/other/directory/"; || die "Couldn't move files: $!\n";
}

See the perldoc of File::Copy for more info.

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