Автор: Тёмный Эльф 9.11.2007 5:45
Код
#! /bin/usr/perl
$dir = <STDIN>;
opendir(dir, '/root') || die "Error: $!";
@FILES = readdir dir;
closedir(dir);
print "$_\n" foreach @FILES;
Помогите пожалуйста разобраться с некоторыми вопросами.
1) что нужно поставить вместо '/root' чтобы путь принимал значение переменной $dir, которую вводит пользователь? Пробовала "$dir" и так '$dir' и просто $dir. Ничего не подходит.
2) и как сделать так чтобы найденные файлы оказались в массиве (с тем чтобы потом этот массив отсортировать). Или может, есть специальная опция, благодаря которой можно будет сразу получить список файлов в алфавитном порядке?
3) readdir dir читает только названия файлов. А можно ли сделать так, чтобы и даты их создания были известны?
Вот такая вот куча вопросов получилась
Автор: xds 9.11.2007 10:34
Вот тебе первый примерчик:
Код
#!/usr/bin/perl
print "Directory to list: ";
$dir = <STDIN>;
chomp $dir;
opendir D, $dir or die "$dir: unable to open directory";
$i = 0;
while ($t = readdir D) {
$names[$i] = $t;
$times[$i] = $stat[10] if @stat = stat "$dir/$t";
$i++;
}
closedir D;
for ($i = 0; $i < @names; $i++) {
if (!$times[$i]) {
$time = "?";
} else {
@_ = localtime $times[$i];
$time = sprintf "%4d-%02d-%02d", $_[5] + 1900, $_[4], $_[3];
}
printf "%10s %s\n", $time, $names[$i];
}
Проблема при чтении строк из STDIN в том, что в конец незаметно добавляется "\n". С этим приходится бороться с помощью функции chomp.
Сортировка массива - функция sort. Сложные структуры данных и их сортировка - отдельная песня, т. к. связана с использованием ссылок (man perlref).
Добавлено через 11 мин. Вот более сложный пример с использованием ссылок и сортировки по указанному условию:
Код
#!/usr/bin/perl
print "Directory to list: ";
$dir = <STDIN>;
chomp $dir;
opendir D, $dir or die "$dir: unable to open directory";
$i = 0;
while ($name = readdir D) {
if (@stat = stat "$dir/$name") {
$ctime = $stat[10];
}
else {
$ctime = 0;
}
$list[$i++] = { 'name' => $name, 'ctime' => $ctime };
}
closedir D;
@list = sort {uc($$a{'name'}) cmp uc($$b{'name'})} @list;
foreach $file (@list) {
if (!$$file{'ctime'}) {
$time = '?';
} else {
@_ = localtime $$file{'ctime'};
$time = sprintf "%4d-%02d-%02d", $_[5] + 1900, $_[4], $_[3];
}
printf "%10s %s\n", $time, $$file{'name'};
}
@list - это массив ссылок на хеши (ассоциативные массивы Perl). В данном случае реализуется аналогия массива указателей на структуры. Сортировка выполняется над ссылками, но сравнение при этом происходит по одному из элементов хеша.
Вообще, аппарат ссылок Perl - очевидно, мощное, но трудное для интуитивного понимания средство. Оно отдает низкоуровневым программированием.
Автор: hiv 9.11.2007 20:52
Цитата(xds @ 9.11.2007 7:34)
Вот тебе ...
xds не обижайся, я твой примерчик слегка упростил. Просто сделал это с использованием хеша и сортировки по его ключу (имя файла там)
Код
#!/usr/bin/perl
print "Directory to list: ";
$dir = <STDIN>;
chomp $dir;
opendir D, $dir or die "$dir: unable to open directory";
$i = 0;
while ($n = readdir D) {
@t = localtime($stat[10]) if @stat = stat "$dir/$n";
$times{$n} = sprintf "%4d-%02d-%02d", $t[5] + 1900, $t[4] + 1, $t[3];;
$i++;
}
closedir D;
foreach (sort keys %times) {
printf "%-20s %s\n", $_, $times{$_};
}
Автор: xds 9.11.2007 21:39
Ну да, так лучше. $i можно тоже убрать.
Автор: Тёмный Эльф 10.11.2007 6:39
Спасибо, ваши примеры очень помогли. =)