Помощь по программе Perl на opendir и readdir - PullRequest
2 голосов
/ 26 ноября 2010

Итак, у меня есть программа для очистки некоторых текстовых файлов.Программа просит пользователя ввести полный путь к каталогу, содержащему эти текстовые файлы.Оттуда я хочу прочитать файлы в каталоге, распечатать их в новый файл (указанный пользователем), а затем очистить их так, как мне нужно.Я уже написал скрипт для очистки текстовых файлов.

Я прошу пользователя указать каталог для использования:

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

Затем мне нужно прочитать каталог.

my @dir = readdir DIR;

foreach (@dir) {

Теперь я потерялся.

Любая помощь, пожалуйста?

Ответы [ 4 ]

2 голосов
/ 26 ноября 2010

Я не уверен, чего ты хочешь. Итак, я сделал несколько предположений:

  • Когда вы сказали «очистить текстовый файл», вы имели в виду удалить текстовый файл
  • Имена файлов, в которые вы хотите записать, образованы шаблоном.

Итак, если я прав, попробуйте что-то вроде этого:

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 $_;
}
1 голос
/ 26 ноября 2010

Сегодня я написал что-то, что использовало 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, являются только базовыми; они не являются полными путями.

1 голос
/ 26 ноября 2010

Я бы предложил вам переключиться на File :: Find. Вначале это может быть сложной задачей, но она мощная и кроссплатформенная.

Но, чтобы ответить на ваш вопрос, попробуйте что-то вроде:

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

где "foo" - это все, что вам нужно сделать с файлами. Несколько примечаний могут помочь:

  • использование "@dir" в качестве массива файлов немного вводило в заблуждение
  • имя папки должно быть добавлено к имени файла, чтобы получить нужный файл
  • может быть удобно использовать grep для удаления ненужных файлов и подпапок, особенно ".."
0 голосов
/ 01 января 2019

Вы можете сделать следующее, что позволяет пользователю указать свой собственный каталог, или, если пользователь не указал каталог, по умолчанию он назначается местоположению.

В примере показано использование opendir, readdir, сохраняет все файлы в каталоге в массиве @files и только файлы, заканчивающиеся на '.txt' в массиве @keys.Цикл 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";
}

См. perldoc File :: Copy для получения дополнительной информации.

...