Анимация
JavaScript
|
Главная Библионтека > Смотри также- perlrun{\); рецепты 7.9; 16.6. При использовании -п или -р для неявного перебора входных данных для всего цикла негласно создается специальная метка LINE:. Это означает, что из внутреннего цикла можно перейти к следующей входной записи командой next LINE (аналог next в awk). При закрытии ARGV происходит переход к следующему файлу (аналог nextfile в awk). Обе возможности продемонстрированы в примере 7.5. Пример 7.5. countchunks #1/usr/bin/perl -n # countchunks - подсчет использованных слов # с пропуском комментариев. При обнаружении END или DATA # происходит переход к следующему файлу for (split /\W+/) { next LINE If /-#/; close ARGV if / (DATAEND) /; $chunks++; END { print "Found Schunks chunks\n" } В файле .history, создаваемым командным интерпретатором tcsh, перед каждой строкой указывается время, измеряемое в секундах с начала эпохи: #+0894382237 less /etc/motd #+0894382239 VI "/.exrc #+0894382242 date #+0894382239 who #+0894382288 telnet home Простейщая однострочная программа приводит его к удобному формату: %рег1 -ре s/"#\+(\d+)\n/localtime($1) . " "/е Tue May 5 09:30:37 1998 less /etc/motd Tue May 5 09:30:39 1998 vi "/.exrc Tue May 5 09:30:42 1998 date Tue May 5 09:30:42 1998 who Tue May 5 09:30:28 1998 telnet home Параметр -i изменяет каждый файл в командной строке. Он описан в рецепте 7.9 и обычно применяется в сочетании с -р. Для работы с национальными наборами символов используется директива use locale. 7.8. Непосредственная модификация файла с применением временной копии Проблема Требуется обновить содержимое файла на месте. При этом допускается применение временного файла. Решение Прочитайте данные из исходного файла, запишите изменения во временный файл и затем переименуйте временный файл в исходный: open(OLD, < open(NEW, < select(NEW); Sold") Snew") while (<OLD>) { # Изменить $ print NEW $ > Glose(OLD) close(NEW) rename($old, rename($new, затем. "Sold.orig") Sold) or die "cant open Sold. $!", or die "cant open Snew $!"; # Новый файловый манипулятор, # используемый print no умолчанию or die cant write $new: S"; or die "cant close Sold $"; or die can t close Snew: S"; or die "can t rename Sold to Sold orig: S! or die "can t rename Snew to Sold. S!"; Такой способ лучше всего приходит для обновления файлов «на месте». Комментарий Этот метод требует меньше памяти, чем другие подходы, не использующие временных файлов. Есть и другие преимущества - наличие резервной копии файла, надежность и простота программирования. Показанная методика позволяет внести в файл те же изменения, что и другие версии, не использующие временных файлов. Например, можно вставить новые строки перед 20-й строкой файла: while (<OLD>) { If (S. == 20) { print NEW "Extra line 1\n"; print NEW "Extra line 2\n"; > print NEW $ ; > Или удалить строки с 20 по 30: while (<OLD>) { next If 20 .. 30; print NEW $ ; > 7.9. Непосредственная модификация файла с помощью параметра -i 259 Обратите внимание: функция rename работает лишь в пределах одного каталога, поэтому временный файл должен находиться в одном каталоге с модифицируемым. Программист-перестраховщик непременно заблокирует файл на время обновления. > Смотри также- Рецепты 7.1; 7.9-7.10 7.9. Непосредственная модификация файла с помощью параметра -i Проблема Требуется обновить файл на месте из командной строки, но вам лень возиться с файловыми операциями из рецепта 7.8. Решение Воспользуйтесь параметрами -i и -р командной строки Perl. Запишите свою программу в виде строки: % perl -i.orig -р ФИЛЬТР файл1 файл2 файлЗ ... Или воспользуйтесь параметрами в самой программе: #!/usr/bin/perl -i.orig -р # Фильтры Комментарий Параметр командной строки -i осуществляет непосредственную модификацию файлов. Он создает временный файл, как и в предыдущем рецепте, однако Perl берет на себя все утомительные хлопоты с файлами. Используйте -i в сочетании с -р (см. рецепт 7.7), чтобы превратить: % perl -pi.ong -е s/DATE/localtime/e в следующий фрагмент: while (о) { if (SARGV ne Soldargv) { # Мы перешли к следующему файлу"? rename($ARGV, $ARGV .orig), open(ARGVOUT, ">$ARGV); # Плюс проверка ошибок select(ARGVOUT); Soldargv = SARGV; s/DATE/localtime/e; continue! Конечно, имеется в виду лень творческая, а не греховная. 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 |