С вашим кодом довольно много проблем:
Второй readdir
(в for my $i (@files)
l oop) ничего не читает с первого. (@files=grep{!/^\./}readdir CWD;
) уже прочитал весь каталог. Вы можете сначала использовать rewinddir
, но просто использовать копию @files
(перед нажатием foo.txt
и bar.txt
) будет проще и эффективнее.
Вы используете !=
вместо ne
для сравнения строк.
Каждая итерация вашего l oop стирает предыдущее значение @differences
с момента его назначения с =
. По-видимому, push
будет иметь больше смысла.
Лог c внутри вашего l oop немного ошибочен. grep
возвращает элементы, которые удовлетворяют условию, но вас больше интересует, удовлетворяют ли ему какие-либо элементы.
Вы должны проверить, удалось ли opendir
(добавив or die ...
на строку opendir
). Также обратите внимание, что open my $CWD, getcwd
эквивалентно более простому open my $CWD, "."
.
То, что вы, вероятно, хотели сделать, это что-то вроде:
use strict;
use warnings;
opendir my $CWD, "." or die "Could not open '.': $!";
my @files = grep{!/^\./} readdir $CWD;
my @init_files = @files;
push @files, ("foo.txt", "bar.txt");
my @difference;
for my $i (@files){
push @difference, (grep { !/^\./ and $i eq $_ } @init_files) ? () : $i;
}
print "$_\n" for @difference
Это далеко не так. однако эффективно и сложнее, чем должно быть. Вместо этого я предлагаю:
my %files = map { $_ => 1 } grep {!/^\./} readdir $CWD;
my @difference;
for ("foo.txt", "bar.txt") {
push @difference, $_ if ! exists $files{$_};
}
print "$_\n" for @difference
Обратите внимание, что я добавил use strict; use warnings;
в сценарий. Всегда добавляйте их в свои коды. Хотя в этом конкретном случае c это не помогло бы вам выяснить, что не так, это сэкономит вам бесчисленное количество часов в будущем. Кроме того, всегда используйте лексические дескрипторы файлов / каталогов (т. Е. opendir my $CWD, "dir"
, а не open CWD, "dir"
).