Программирование на perl — чтение дескриптора
opendir(WORK,"/bin/work");
Б. Операция closedir закрывает дескриптор каталога
closedir (WORK);
В. Чтение дескриптора
readdir (WORK);
Один элемент списка – одно имя файла. Здесь только один аргумент – это имя дескриптора каталога. В скалярном контексте возвращает следующее имя файла (только основное имя без всяких слешей в том порядке, в котором они находятся в файловой системе). Если имен нет, то возвращается undef. А в списочном контексте происходит возврат всех остальных имен файлов.
Пример. Вывод имен по алфавиту.
opendir (WORK,"/work")|| warn ("Не могу открыть:$!");
# Получение имен в списочном контексте с сортировкой.
foreach $name (sort readdir(WORK));
{ print "$namen";
}
closedir (WORK);
3. Развертывание.
Получение списка имен файлов по шаблону.
Шаблоны – как в DOS, но с элементами регулярного выражения.
* — все
? – один любой символ
[a-m] – любая буква от a до m.
Специальные символы здесь и в регулярных выражениях имеют часто совершенно разный смысл.
Развертывание может быть методом А или методом Б.
А. С помощью угловых скобок
@a=</work/*.c>; # Получение всех имен файлов,
# заканчивающихся на символы .с.
Б. С помощью функции
@b=glob("/work/*c"); # В аргументе функции glob и <>
# возможна интерполяция переменных,
# то-есть развертывание происходит
# динамически.
В списочном контексте возвращается список всех имен, что совпадают с образцом или пустой список, если совпадений нет.
В скалярном — следующее совпадающее имя, а если совпадений нет – то undef.
Внутри аргумента можно несколько образцов:
$f_b=<fred* barney*>;
Здесь каждый список развертывается отдельно, а потом они конкатенируются так, как будто это один большой список.
4. Создание и удаление.
А. Создание
mkdir ("new_dir", п_доступа);
new_dir – имя нового каталога;
п_доступа – число, равное правам доступа к каталогу.
Б. Удаление пустого каталога
rmdir (name_dir);
В. Изменение прав доступа
Как команда в UNIX с тем же названием.
chmod (n,"имя1","имя2");
n – восьмеричное число из трех цифр
n=0x1x2x3
xi=0..7
x1 – для владельца;
x2 – для группы;
x3 – для всех.
Любое xi должно быть представлено тремя цифрами двоичной системы:
xi=b1b2b3
b1 – для чтения;
b2 – для записи;
b3 – для выполнения.
Пример
chmod (0666,"fred","barney");
Файлы – для чтения и записи.
Возвращает число файлов, для которых успешно изменены права доступа, даже если ничего в результате фактически не изменилось. Поэтому для контроля лучше всего цикл по одному файлу.
Существуют команды для изменения принадлежности файла:
Chown (UID, GID, имена_файлв);
Здесь UID и GID – только числа. Если какой-то ID не нужен, то вместо него ставится "минус единица".
Пример:
Chown (1234, 35, "my", "your");
Здесь 1234 – идентификатор пользователя, а 35 – идентификатор группы.
Г. Изменение меток времени.
Для любого файла – 3 отметки:
atime – время последнего доступа;
mtime — время последнего изменения;
ctime – время последнего изменения индексного дескрипторв.
Все эти времена обрабатываются функцией utime(). utime() можно присваивать произвольные значения для atime и mtime, после чего ctime – автоматически устанавливается в текущее время. Все значения в секундах с 1.1.1970 00:00:00 по Гринвичу. Високосный год не учитывается. Каждый год – это
31 536 000 секунд.
Пример
$atime=$mtime= 700000000; # То-есть некоторое время назад,
# так как сейчас порядка
# 940 000 000 секунд.
utime ($atime,$mtime, "fred","barn");
# Как будто файлы "fred" и "barn"
# изменились в недавнем прошлом
Функция time() без параметров возвращает текущее время.
Это время в секундах с 1.01.1970 г. 00:00:00 без учета високосных лет. Для наших дней примерно 950 000 000 сек.
Получение даты и времени
Функция localtime()
Возвращает список из 9 элементов для локальной зоны. Они все числовые значения, аналогично языку Си. Если функция применена без аргументов, то преобразует текущее время.
Преобразует значение, полученное функцией time().
Элементы списка:
$sec 0-59
$min 0-59
$hour 0-23
$mday день месяца
$mon месяц 0-11
$year год – 1900
$wday день недели 0-6
$yday день года
$isdst
Пример:
$day=(sun, mon, tue, wed, thu, fri, sat)[(localtime)[6]];
# Здесь [6] – это получение $wday, то-есть дня недели. Потом из # списка извлекается тот элемент, номер которого находится в
# $wday.
print "$day=$dayn";
Будет выведено
$day=sat
Есть еще функции для времени:
gmtime – аналогично localtime, только время по Гринвичу.
times – четырехэлементный список для процессорного времени пользователя и системы для процесса и его потока в секундах. Секунды могут быть выражены дробью.
Сложные структуры данных
I. Многомерные массивы (список списков)
1. Строение
А. Без указателей
@LoL=(
["a1","b1"],
["a2","b2","c2"],
["a3","b3","c3"]
);
Здесь необходимо обратить внимание на:
— LoL – это переменная-массив;
— что здесь составляется список, то0есть значения в круглых скобках;
— каждая строка – это один элемент, но в квадратных скобках;
— все строки – через запятую. Двойные кавычки не нужны, если в них есть числа.
Б. С указателями
$ref_to_LoL=[
["a1","b1"],
["a2","b2","c2"],
["a3","b3","c3"]
];
Здесь $ref_to_LoL – это скалярная переменная, а не массив.
Не будет ошибкой, если после последних элементов будут стоять запятые, например, ["a1","b1",] и ["a3","b3","c3",],.
2. Создание
А. Самый простой
Цикл по $i, цикл по $j
$LoL[$i][$j]= Константа
или
$LoL[$i][$j]= Выражение
Б. Используя данные файла или подпрограммы
while (<>)
{ @tmp=split; # С помощью временного массива,
# который является одномерным
# массивом и содержит строку
# файла. Операция split
# рассщепляет строку на элементы
# массива
push @LoL,[@tmp]; # оператором push справа
# добавляем в массив @LoL
# еше строку
}
или
while (<>)
{ push @LoL,[split]; # Здесь то же самое, только
# без временного массива
}
for $i (0..5)
[$LoL[$i]=[func($i)];] # Здесь func($i) –
# подпрограмма,
# вырабатывающая список
# значений, то-есть сразу
# несколько элементов
# одномерного массива.
# Кроме того в левой части
# стоит элемент двумерного
# массива, то-есть его
# строка. Причем этот
# элемент – это не строка-
# массив, а указатель на
# нее, то-есть – $LoL[$i]
# это указатель
или
for $i (0..5) # Следующие два примера –
# опять данные из файла.
# Причем здесь $line – это
# строка, а не массив.
# Разделение строки идет по
# пробелу.
{ $line=<>;
$LoL[$i]=[split ‘ ‘,$line];
}
или
for $i (0..5) # Здесь без применения
# дополнительных элементов.
{ $LoL[$i]= [split ‘ ‘,<>];
}
Если применяем
$ref_to_LoL
то можно так:
while (<>)
{ push @ref_to_LoL, [split];
}
Здесь $ref_to_LoL – это указатедь. Так как в операторе push первый аргумент всегда массив, то мы по сути разыменвыем ссылку, то-есть получаем массив.
Если есть временный массив @list, то еего к массиву @LoL можно добавить:
— $LoL[$i]=[@list]; # Здесь к указателю добавляем
# сложный элемент, то-есть то, что
# в квадратных скобках.
или
— @{$LoL[$i]}=@list; # Здесь массив @list не менем, но
# разыменовываем элемент
# (указатель) в квадратных
# скобках.
3. Доступ и печать
А. К массиву @LoL
— $LoL[$i][$j]
Например,
$LoL[1][1]=> "b2" # Здесь обычный подход
— можно и так:
$LoL[$i]->[$j]
Т. е.
$LoL[1]->[1]=> "b2" # Здесь через элементы-
# строки, которые являются
# указателями.
Б. Если указатель $ref_to_LoL
— $ref_to_LoL->[$i][$j]
тогда $reg_to_LoL->[1][1] ссылактся на "b2". При доступе к элементу массива через указатель необходимо ставить операцию ->.
—
Можно и так
$ref_to_LoL->[$i]->[$j]
тогда $ref_to_LoL->[$1]->[$2] ссылается на "b2".