Анимация
JavaScript


Главная  Библионтека 

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 [ 79 ] 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242

warn "Cant open $ARGV; $!\n"; next;

>

while (defined($ = <ARGV>)) { #...

Внутри цикла с помощью ARGV и $ARGV можно получить дополнительные данные или узнать имя текущего обрабатываемого файла. Давайте посмотрим, как это делается.

Общие принципы

Если пользователь не передает аргументы, Perl заносит в @ARGV единственную строку, -". Это сокращенное обозначение соответствует STDIN при открытии для чтения и STDOUT - для записи. Кроме того, пользователь может передать " -" в командной строке вместо имени файла для получения входных данных из STDIN.

Далее в цикле из @ARGV последовательно извлекаются аргументы, а имена файлов копируются в глобальную переменную $ARGV. Если файл не удается открыть, Perl переходит к следующему файлу. В противном случае начинается циклическая обработка строк открытого файла. После заверщения обработки открывается следующий файл, и процесс повторяется до тех пор, пока не будет исчерпано все содержимое @ARGV.

При вызове open не используется форма open(ARGV, "> $ARGV"). Это позволяет добиться интересных эффектов - например, передать в качестве аргумента строку "gzip -de file.gz ", чтобы программа получила в качестве входных данных результаты команды "gzip -de file. gz". Такое применение open рассматривается в рецепте 16.15,

Массив @ARGV может изменяться перед циклом или внутри него. Предположим, вы хотите, чтобы при отсутствии аргументов входные данные читались не из STDIN, а из всех программных и заголовочных файлов С и С++. Вставьте следующую строку перед началом обработки <ARGV>:

©ARGV = glob("..[Cch]") unless ©ARGV;

Перед началом цикла следует обработать аргументы командной строки - либо с помощью модулей Getopt (см. главу 15 «Пользовательские интерфейсы»), либо вручную:

# Аргументы 1: Обработка необязательного флага -с if (©ARGV && $ARGV[0] eq -с) {

$chop first++; shift;

# Аргументы 2: Обработка необязательного флага -NUMBER if (@ARGV && $ARGV[0] = /"-(\d+)$/) {

Scolumns = $1; shift;



# Аргументы 3: Обработка сгруппированных флагов -а, -i -п, и -и while {©ARGV && $ARGV[0] =" /"-{+)/ & (shift, ($ = $1), 1)) { next if /"$/;

s/a && (++$append, redo);

s/i && (++$ignore ints, redo); s/n && (++$nostdout, redo); s/u && (++$unbuffer, redo); die "usage: $0 [-ainu] [filenames] ...\n";

>

Если не считать неявного перебора аргументов командной строки, <> не выделяется ничем особенным. Продолжают действовать все специальные переменные, управляющие процессом ввода/вывода (см. главу 8). Переменная $/ определяет разделитель записей, а $. содержит номер текущей строки (записи). Если $/ присваивается неопределенное значение, то при каждой операции чтения будет получено не объединенное содержимое всех файлов, а полное содержимое одного файла:

undef $/; while (о) {

# Теперь в $ находится полное содержимое файла,

# имя которого хранится в $AR6V

>

Если значение $/ локализовано, старое значение автоматически восстанавливается при выходе из блока:

{ # Блок для local

local $/; # Разделитель записей становится неопределенным while (О) {

# Сделать что-то; в вызываемых функциях

# значение $/ остается неопределенным

} # Восстановить $/

Поскольку при обработке <ARGV> файловые манипуляторы никогда не закрываются явно, номер записи $. не сбрасывается. Если вас это не устраивает, самостоятельно организуйте явное закрытие файлов для сброса $.:

while (о) {

print "$ARGV:$.:$ "; close AR6V if eof;

Функция eof проверяет достижение конца файла при последней операции чтения. Поскольку последнее чтение выполнялось через манипулятор ARGV, eof сообщает, что мы находимся в конце текущего файла. В этом случае файл закрывается, а переменная $. сбрасывается. С другой стороны, специальная запись eof () с круглыми скобками, но без аргументов проверяет достижение конца всех файлов при обработке <ARGV>.



256 Глава 7 • Доступ к файлам Параметры командной строки

В Perl предусмотрены специальные параметры командной строки -п, -р и -i, упрощающие написание фильтров и однострочных программ.

Параметр -п помещает исходный текст программы внутрь цикла while(<>). Обычно он используется в фильтрах типа grep или программах, которые накапливают статистику по прочитанным данным.

Пример 7.1. fmdloginl

#!/usr/bin/perl

# findlogini - вывести все строки, содержащие подстроку "login" while (о) { # Перебор файлов в командной строке

print if /login/;

>

Программу из примера 7.1 можно записать так, как показано в примере 7.2.

Пример 7.2. fmdloginZ

#!/usr/bin/perl -n

ft findlogin2 - вывести все строки, содержащие подстроку "login" print if /login/;

Параметр -n может объединяться с -е для выполнения кода Perl из командной строки:

% perl -ne print if /login/

Параметр -p аналогичен -n, однако он добавляет print в конец цикла. Обычно он используется в программах для преобразования входных данных.

Пример 7.3. lowercasel

»!/usr/bin/perl

# lowercase - преобразование всех строк в нижний регистр use locale;

while (о) { # Перебор в командной строке

s/(["\W0-9 ])/\l$1/g; # Перевод всех букв в нижний регистр print;

Программу из примера 7.3 можно записать так, как показано в примере 7.4. Пример 7.4. lowercaseZ

#!/usr/bin/perl -р

# lowercase - преобразование всех строк в нижний регистр use locale;

s/(["\W0-9 ])/\l$1/g; # Перевод всех букв в нижний регистр Или непосредственно в командной строке следующего вида; % perl -Mlocale -ре s/(["\W0-9 ])/\1$1/g



0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 [ 79 ] 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242