Операция ()
При выполнении операции ввода из файла встроенная переменная $. на каждом шаге цикла хранит номер прочитанной строки файла. В случае задания нескольких имен файлов в командной строке при последовательном вводе их строк операцией о эта переменная продолжает увеличивать свое значение при переходе на чтение строк очередного файла, т. е. она рассматривает содержимое всех файлов как один-единственный файл.
Операцию () и массив @ARGV можно совместно использовать для ввода в программу содержимого нескольких файлов, не связывая их с заданием имен файлов в командной строке. В любом месте программы перед первым использованием в цикле операции ввода <> можно в массив SARGV занести имена файлов, содержимое которых необходимо обработать:
@ARGV = ("filel.dat", "file2.dat", "file3.dat"); for (;<>;) {Операторы обработки строк файлов }
Этот фрагмент программы в цикле for последовательно обработает строки трех файлов file1.dat, file2.dat и file3.dat. Здесь же продемонстрирована еще одна интересная особенность операции ввода о. Обычно прочитанная этой операцией строка присваивается скалярной переменной, как это происходило в примере 6.4, но если эта операция одна представляет выражение условия цикла, то результат ее выполнения сохраняется в специальной встроенной переменной $_. Цикл while программы примера 6.4 можно записать и так:
while (<>) (print; }
Здесь также используется то обстоятельство, что функция print без параметров по умолчанию выводит содержимое переменной $_.
Если мы хотим передать в программу некоторые ключи, устанавливающие режим ее работы, то в начале программы следует поместить цикл, который проверяет содержимое массива @ARGV на наличие ключей в командной строке вызова программы. Один из способов подобной проверки приводится в примере 6.5, где предполагается, что программе могут быть переданы ключи:
-d, -s и -е. f! peri – w while ($_ = $ARGV[0], / ^ – /) { if(/ ^ – d/) { print $ARGV[0],"\n";} if(/ ^ – s/) { print $ARGV[0]-, "\n"; } 1£(/ ^ – е/) { print $ARGV[0],"\n"; } SHIFT; }
При вычислении выражения условия цикла while осуществляется присваивание переменной $_ значения первого элемента массива @ARGV и проверка присутствия дефиса "-" в качестве первого символа содержимого этой переменной (операция / ^ – /). Операторы if проверяют содержимое переменной $_ на соответствие известным ключам и отображают их. (В реальных программах в этих операторах обычно определяют некоторые переменные, которые в дальнейшем используются для выполнения действий, присущих соответствующим ключам.) Функция SHIFT удаляет из массива @ARGV первое значение, сдвигая оставшиеся в нем элементы на одну позицию влево: второй становится первым, третий вторым и т. д.
Цикл повторяется до тех пор, пока переданные через командную строку параметры начинаются с дефиса. Еще одно применение операции <> связано с получением в программе имен файлов определенного каталога, удовлетворяющих заданному шаблону. Если в качестве операнда этой операции используется шаблон имен файлов, то в скалярном контексте она возвращает первое найденное имя файла в текущем каталоге, в списковом контексте – список имен файлов, удовлетворяющих заданному шаблону. (В шаблоне можно использовать метасимволы: * для произвольной цепочки символов,? для произвольного одиночного символа.) Если в каталоге не найдены файлы с именами, удовлетворяющими шаблону, то операция возвращает неопределенное значение. Например, выполнение следующей операции:
$first = <*.pl>;
…приведет к сохранению в переменной $ first имени первого файла из списка всех файлов текущего каталога с расширением pl, если таковые файлы в каталоге есть, иначе эта переменная будет иметь неопределенное значение. В списке файлы упорядочены в алфавитном порядке. Эта же операция в списковом контексте:
gfiles = <*.pl>;
…возвращает список всех файлов с расширением pl. После выполнения этой операции элементы массива @files содержат имена всех файлов с расширением pl.
Замечание
Имена подкаталогов текущего каталога считаются файлами без расширения. Например, в возвращаемом операцией <*. *> списке файлов будут содержаться и имена подкаталогов текущего каталога.
Если при задании шаблона файла явно указать каталог, то эта операция возвратит список файлов из указанного каталога, имена которых удовлетворяют заданному шаблону. Например, операция:
@files = </perl/*.pl>;
…сохранит в массиве @flies имена всех файлов каталога /perl с расширением pl.
Замечание
В системе Windows эта операция найдет все файлы с расширением рl в каталоге /perl текущего диска. Для задания конкретного диска следует использовать принятый в Windows синтаксис для полного имени файла: <d: /perl/*. *>. Эта операция возвратит список всех файлов каталога /perl, расположенного на диске d:.
При использовании этой операции в выражении условия цикла while или for она последовательно на каждом шаге цикла возвращает очередное имя файла, удовлетворяющее заданному шаблону:
while ($file = <*.pl>) ( print "$file\n"; }
Употребленная в выражении условия самостоятельно, эта операция возвращает очередное имя файла в переменной $_. Например, предыдущий фрагмент можно переписать следующим образом:
while (<*.pl>) { print $_, "\п"; }
Операция получения имен файлов, соответствующих заданному шаблону, реализуется с помощью внутренней функции glob, единственным параметром которой является шаблон имен файлов. Эту функцию можно использовать самостоятельно для получения соответствующих имен файлов:
@scripts = glob "*.pl";
В скалярном контексте она возвращает имя первого файла, удовлетворяющего заданному шаблону, в списковом – список имен всех файлов. Употребленная без параметра, она использует в качестве параметра специальную переменную $_.