Глава 12: Доступ к каталогам.
12.2 Развертывание
Если в качестве аргумента в командной строке стоит звездочка (*), то shell (или тот интерпретатор командной строки, которым вы пользуетесь) интерпретирует ее как список имен всех файлов, находящихся в текущем каталоге. Так, если вы дали команду rm *, то она удалит все файлы из текущего каталога. (Не делайте этого, если не хотите потом долго приставать к системному администратору с просьбами о восстановлении файлов.) Еще примеры: аргумент [а-т] *. с превращается в список имен файлов, находящихся в текущем каталоге, которые начинаются с одной из букв первой половины алфавита и заканчиваются на .с, а аргумент /etc/host* — в список имен файлов каталога /etc, которые начинаются со слова host. (Если для вас это ново, то перед дальнейшей работой рекомендуем почитать дополнительную литературу о сценариях shell.)
Преобразование аргументов вроде * или /etc/host* в список соответствующих имен файлов называется развертыванием (globbing). Perl обеспечивает развертывание с помощью очень простого механизма: подлежащий развертыванию образец заключается в угловые скобки или же используется функция glob.
@а = </etc/host*>
@а = glob("/de/host*");
В списочном контексте, как показано выше, результатом развертывания является список всех имен, которые совпадают с образцом (как если бы shell раскрыл указанные аргументы), или пустой список, если совпадения не обнаружено. В скалярном контексте возвращается следующее совпадающее имя, а если совпадений нет — возвращается undef; это очень похоже на чтение из дескриптора файла. Например, просмотр имен по одному реализуется с помощью следующего кода:
while (defined($nextname = </etc/host*>)) {
print "one of the files is $nextname\n";
}
* Это справедливо для UNIX и большинства других современных операционных систем.
Здесь возвращенные имена файлов начинаются с префикса, соответствующего пути доступа к ним (/etc/host), поэтому, если вам нужна только последняя часть имени, придется выделять ее самостоятельно, например:
while ($nextname = </etc/host*>) {
$nextname =~ s#.*/##; # удалить часть до последней косой черты
print "one of the files is $nextname\n";
}
Внутри аргумента допускается указывать несколько образцов; эти списки развертываются отдельно, а затем конкатенируются так, как будто это один большой список:
@fred_barney_files = <fred* barney*>;
Другими словами, эта операция развертывания выдает те же значения, которые возвратила бы эквивалентная ей команда echo с такими же параметрами.*
Хотя развертывание списка файлов и сопоставление с регулярным выражением осуществляются почти одинаково, специальные символы имеют совершенно разный смысл. Не путайте эти механизмы, иначе будете удивляться, почему вдруг <\. с$> не находит все файлы, имена которых заканчиваются на .с!
В аргументе функции glob перед развертыванием производится интерполяция переменных. С помощью Perl-переменных можно выбирать файлы, задаваемые строкой, вычисляемой во время выполнения:
if (-d. "/usr/etc") {
$where = "/usr/etc";
} else {
$where = "/etc";
}
Sfiles = <$where/*>;
Здесь переменной $where присваивается одно из двух имен каталогов в зависимости от того, существует каталог /usr/etc или нет. Затем мы получаем список файлов, находящихся в выбранном каталоге. Обратите внимание:
переменная $where является развертываемой, т.е. подлежащими развертыванию символами являются /etc/* или /usr/etc/*.
Есть одно исключение из этого правила: образец <$var> (который означает использование в качестве развертываемого выражения переменной $var) должен записываться как <${var}>. В причины появления этого исключения сейчас лучше не вдаваться.**
* Для вас не будет сюрпризом узнать о том, что для выполнения развертывания Perl просто запускает C-shell, который раскрывает указанный список аргументов, и производит синтаксический анализ того, что получает обратно.
** Конструкция <$fred> читает строку из дескриптора файла, заданного содержимым скалярной переменной $fred. Наряду с некоторыми другими особенностями, не упомянутыми в нашей книге, эта конструкция позволяет использовать косвенные дескрипторы файлов, где имя дескриптора передается и обрабатывается так, как будто это данные.
Назад | Вперед
Содержание (общее) | Содержание раздела
Если Вы не нашли что искали, то рекомендую воспользоваться поиском по сайту:
|