Perl-скрипт, который хранит все каталоги и файлы верхнего уровня в массиве

#perl

#perl

Вопрос:

Я считаю, что я делаю это слишком сложным. Мне нужен скрипт, который хранит все каталоги и файлы верхнего уровня (в текущем рабочем каталоге) в массив.

Это то, что у меня есть:

 #!/usr/bin/perl

use strict;
use warnings;

my $dir = 'C:tmp';
my @names = ();
opendir(DIR, $dir) or die $!;

while (my $file = readdir(DIR)) {

    next if ($file =~ m/^./);
    $file = "$file"." ";
    # print "$file";
    @names = split( /s /,$file);
    foreach my $slot (@names) {
    $slot = "$slot"." ";
    }
    print @names;
}
closedir(DIR);
exit 0;
 

Хотя это работает, я знаю, что это очень неаккуратно, и я чрезмерно усложняю это, но я не могу придумать ничего, что могло бы упростить это. Я стараюсь избегать использования каких-либо модулей perl, кроме самых базовых (File::Find в порядке, но любые модули cnet — нет). Итак, мой вопрос в том, как я могу это упростить? Спасибо

Комментарии:

1. просто понял, что это бессмысленно делать. Так что без понятия, ха-ха.

Ответ №1:

Это может быть то, что вы хотите,

 my @names = grep !/^[.]{1,2}$/, readdir(DIR);
 

ваш цикл можно сократить до

 while (my $file = readdir(DIR)) {

    next if $file =~ /^./;
    $file =~ s/s / /g;
    $file .= " ";
    print $file;
}
 

если это имеет какой-то смысл?

Комментарии:

1. Эта первая строка была именно тем, что мне было нужно! Спасибо! Мне нужно улучшить регулярное выражение. Не могли бы вы объяснить, что это делает, если у вас есть время?

2. Метод File::Spec no_upwards является достойной альтернативой для фильтрации текущего и верхнего сегментов рабочего каталога из списка имен.

3. @user3646369 он будет считывать каталог в @names, отфильтровывая . и .. элементы.

Ответ №2:

Вы могли бы использовать библиотеку File::Slurp следующим образом:

 #!/usr/bin/perl

use File::Slurp;

my @files = read_dir('C:tmp');
 

Комментарии:

1. Это кажется действительно простым способом сделать это, к сожалению, я должен избегать любых pm, которые не являются самыми простыми. Это модуль cnet, поэтому я не могу его использовать. Но все же спасибо!

2. @user3646369: Ты имеешь в виду Скайнет? : D

3. Если вы не используете модули cpan, тогда какой смысл использовать Perl?

Ответ №3:

Вы что-то недопонимаете, но я не совсем уверен, что именно. В нем всегда есть только одно имя файла $file , и нет смысла добавлять пробел перед разделением на пробелы

Ваш массив @names будет содержать фрагменты имени файла, разделенные пробелами, если в нем есть пробелы, в противном случае это будет просто исходное имя файла

Затем вы помещаете пробелы в конце каждого элемента @names , предположительно, для замены удаленных на split , поэтому мне интересно, почему вы использовали split в первую очередь

Наконец, print @names выведет повторно собранное имя файла с дополнительным пробелом в конце. Обратите внимание, что если в вашем исходном имени файла было несколько пробелов, теперь они будут сведены к одному пробелу

Самый простой способ распечатать массив строк, разделенных пробелами, — это интерполировать его в строку, заключенную в двойные кавычки

Эта программа выполняет то, что вы просили, но оставляет исходные имена файлов нетронутыми. Он использует grep для ввода @names только те имена файлов, которые не начинаются с точки . . Он также использует лексический дескриптор каталога, который является современной передовой практикой

 use strict;
use warnings;

my $dir = 'C:tmp';
opendir my $dh, $dir or die $!;
my @names = grep /^[^.]/, readdir $dh;
print "@namesn";
 

Комментарии:

1. Возможно, ваше регулярное выражение фильтра должно быть более гибким, поскольку оно вполне допустимо для имен файлов, начинающихся с . т.е. .htaccess, .bashrc и т. Д. (Хотя OP использует аналогичное регулярное выражение).

2. @Chris: Возможно, но я написал его так, чтобы он выдавал результат, эквивалентный коду OP. Я понятия не имею, это то, что он имел в виду

3. Я понял, что добавление этих дополнительных пробелов означало, что я был глуп и забыл, как формируются массивы. Когда я печатал массив перед этим, между элементами не было пробелов, что заставило меня глупо думать, что это неправильно. Итак, я запутался. Но ваш ответ решает мою проблему, так что спасибо!

4. @user3646369: если вы напишете print @names , содержимое будет напечатано без пробелов. Но если вы используете "@names" , то строка создается из элементов массива с пробелами между ними. На самом деле, они разделены текущим значением встроенной переменной $" , которая изначально задается пробелом, но может быть изменена для разных эффектов. Например, local $" = ', ' будет ставить запятую и пробел между элементами или local $" = ',' может быть полезен для генерации CSV-данных.