Помощь - Поиск - Пользователи - Календарь
Полная версия: Perl
Форум «Всё о Паскале» > Современный Паскаль и другие языки > Ада и другие языки
Тёмный Эльф
Код
#! /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) и как сделать так чтобы найденные файлы оказались в массиве (с тем чтобы потом этот массив отсортировать). Или может, есть специальная опция, благодаря которой можно будет сразу получить список файлов в алфавитном порядке? smile.gif
3) readdir dir читает только названия файлов. А можно ли сделать так, чтобы и даты их создания были известны?

Вот такая вот куча вопросов получилась wink.gif
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 ($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
Цитата(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
Ну да, так лучше. $i можно тоже убрать.
Тёмный Эльф
Спасибо, ваши примеры очень помогли. =)
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.