Как я могу получить список всех файлов с определенным расширением из определенного каталога? - PullRequest
11 голосов
/ 02 октября 2009

Я использую этот код для получения списка всех файлов в определенном каталоге:

opendir DIR, $dir or die "cannot open dir $dir: $!";
my @files= readdir DIR;
closedir DIR;

Как я могу изменить этот код или добавить что-то к нему, чтобы он только просматривал текстовые файлы и загружал массив только с префиксом имени файла?

Пример содержимого каталога:

.
..
923847.txt
98398523.txt
198.txt
deisi.jpg
oisoifs.gif
lksdjl.exe

Пример содержимого массива:

files[0]=923847 
files[1]=98398523
files[2]=198

Ответы [ 6 ]

11 голосов
/ 02 октября 2009
my @files = glob "$dir/*.txt";
for (0..$#files){
  $files[$_] =~ s/\.txt$//;
}
5 голосов
/ 02 октября 2009

достаточно изменить одну строку:

my @files= map{s/\.[^.]+$//;$_}grep {/\.txt$/} readdir DIR;
3 голосов
/ 02 октября 2009

Если вы можете использовать новые функции Perl 5.10, я бы так написал.

use strict;
use warnings;
use 5.10.1;
use autodie; # don't need to check the output of opendir now

my $dir = ".";

{
  opendir my($dirhandle), $dir;
  for( readdir $dirhandle ){ # sets $_
    when(-d $_ ){ next } # skip directories
    when(/^[.]/){ next } # skip dot-files

    when(/(.+)[.]txt$/){ say "text file: ", $1 }
    default{
      say "other file: ", $_;
    }
  }
  # $dirhandle is automatically closed here
}

Или, если у вас очень большие каталоги, вы можете использовать цикл while.

{
  opendir my($dirhandle), $dir;
  while( my $elem = readdir $dirhandle ){
    given( $elem ){ # sets $_
      when(-d $_ ){ next } # skip directories
      when(/^[.]/){ next } # skip dot-files

      when(/(.+)[.]txt$/){ say "text file: ", $1 }
      default{
        say "other file: ", $_;
      }
    }
  }
}
2 голосов
/ 22 декабря 2012

Это самый простой способ, который я нашел (как в удобочитаемом для человека), используя функцию glob:

 # Store only TXT-files in the @files array using glob
 my @files = grep ( -f ,<*.txt>);
 # Write them out
 foreach $file (@files) {
  print "$file\n";
 }

Кроме того, "-f" гарантирует, что в массиве хранятся только фактические файлы (а не каталоги).

2 голосов
/ 02 октября 2009

Чтобы получить только файлы ".txt", вы можете использовать оператор проверки файлов (-f: обычный файл) и регулярное выражение.

my @files = grep { -f && /\.txt$/ } readdir $dir;

В противном случае вы можете искать только текстовые файлы, используя perl's -T (оператор проверки текстового файла ascii)

my @files = grep { -T } readdir $dir;
1 голос
/ 02 октября 2009

Просто используйте это:

my @files = map {-f && s{\.txt\z}{} ? $_ : ()} readdir DIR;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...