#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-данных.