Анимация
JavaScript
|
Главная Библионтека 9.9. Переименование файлов 341 for (@ARGV) { $was = $ ; eval $op; die $@ if $@; rename($was, $ ) unless $was eq $ ; Первый аргумент сценария - код Perl, который изменяет имя файла, хранящееся в $ , и определяет алгоритм переименования. Вся черная работа поручается функции eval. Кроме того, сценарий пропускает вызов rename в том случае, если имя осталось прежним. Это позволяет просто использовать универсальные символы (rename EXPR *) вместо составления длинных списков имен. Приведем пять примеров вызова программы rename из командного интерпретатора: % rename s/\.orig$ ♦.orig % rename tr/A-Z/a-z/ unless /"Make/ % rename $ .= ".bad" .f % rename print "$ : "; s/foo/bar/ if <STDIN> =" /"y/i * % find /tmp -name •" -print rename s/"(.+)$/.#$1/ Первая команда удаляет из имен файлов суффикс .orig. Вторая команда преобразует символы верхнего регистра в символы нижнего регистра. Поскольку вместо функции 1с используется прямая трансляция, такое преобразование не учитывает локальный контекст. Проблема рещается следующим образом: % rename use locale; $ = 1с($ ) unless/"Make/ * Третья команда добавляет суффикс .bad к каждому файлу Fortran с суффиксом ". f " - давняя мечта многих программистов. Четвертая команда переименовывает файлы в диалоге с пользователем. Имя каждого файла отправляется на стандартный вывод, а из стандартного ввода читается ответ. Если пользователь вводит строку, начинающуюся с "у " или "Y", то все экземпляры "foo в имени файла заменяются на "bar". Пятая команда с помощью find ищет в /Шр файлы, имена которых заканчиваются тильдой. Файлы переименовываются так, чтобы они начинались с префикса .#. В сущности, мы переключаемся между двумя распространенными конвенциями выбора имен файлов, содержащих резервные копии. В сценарии rename воплощена вся мощь философии UNIX, основанной на утилитах и фильтрах. Конечно, можно написать специальную команду для преобразования символов в нижний регистр, однако ничуть не сложнее написать гибкую, универсальную утилиту с внутренним eval. Позволяя читать имена файлов из стандартного ввода, мы избавляемся от необходимости рекурсивного перебора каталога. Вместо этого мы используем функцию find, которая прекрасно справляется с этой задачей. Не стоит изобретать колесо, хотя модуль File::Find позволяет это сделать. t> Смотри также- Описание функции rename Bpetifunc(i); страницы руководства mv(l) и гепате(2); документация по стандартному модулю File::Fincl. th = /usr/lib/libca; Sfile = basename(Spath); Sdir = dirname(Spath); print "dir is Sdir, file is $file\n"; tt dir is /usr/lib, file is libc.a Функция f ileparse может использоваться для извлечения расширений. Для этого передайте f ileparse полное имя и регулярное выражение для поиска расширения. Шаблон необходим из-за того, что расширения не всегда отделяются точкой. Например, что считать расширением в ".tar.gz" - ".tar", ".gz" или ". tar.gz"? Передавая шаблон, вы определяете, какой из перечисленных вариантов будет возвращен: Spath = /usr/lib/libca; (Sname,Sdir,Sext) = fileparse(Spath,\..*); print "dir is Sdir, name is Sname, extension is $ext\n"; tt dir is /usr/lib/, name is libc, extension is .a По умолчанию в работе этих функций используются разделитель, определяемый стандартными правилами вашей операционной системы. Для этого используется переменная $~0; содержащаяся в ней строка идентифицирует текущую систему. Ее значение определяется в момент построения и установки Perl. Значение но умолчанию можно установить с помощью функции fileparse set fstype. В результате изменится и поведение функций File::Basenarae при последующих вызовах: 9.10. Деление имени файла на компоненты Проблема Имеется строка, содержащая полное имя файла. Из нее необходимо извлечь компоненты (имя, каталог, расширение (-я)). Решение Воспользуйтесь функциями стандартного модуля File:;Basename. use File;:Basenarae; $base = basename($path); Sdir = dirname($path); ($base, Sdir, Sext) = fileparse(Spath); Комментарий Функции деления имени файла присутствуют в стандартном модуле File::Base-паше. Функции dirname и basename возвращают соответственно каталог и имя файла: 9.11. Программа: symirror 343 fileparse set fstype("MacOS"); Spath = Hard%20Drive:System%20Folder:README.txt"; ($nanie,$dir,$ext) = fileparse($path, Л..«); print "dir is $dir, name is $name, extension is $ext\n"; # dir is Hard%20Drive:System%20Folder, name is README, extension is .txt Расширение можно получить следующим образом: , sub extension { my Spath = shift; my Sext = (fileparse($path. Л-*))[2]; Sext =- s/-\. ; return Sext; Для файла source.c.bak вместо простого "bak" будет возвращено расширение "с. bak". Если вы хотите получить именно "bak", в качестве второго аргумента f ileparse используйте \ . . *?. Если передаваемое полное имя заканчивается разделителем каталогов (например, lib/), f ileparse считает, что имя каталога равно "lib/", тогда как dirname считает его равным ". . 1> Смотри также- Описание переменной $"0 вperlva?-{i); документация но стандартному модулю FiIe::Basenaffle. 9.11. Программа: symirror Программа из примера 9.6 рекурсивно воспроизводит каталог со всем содержимым и создает множество символических ссылок, указывающих на исходные файлы. Пример 9.6. symirror #!/usr/bin/perl -w # symirror - дублирование каталога с помощью символических ссылок use strict; use File;;Find; use Cwd; my (Ssrcdir, Sdstdir); my Scwd = getcwdO; die "usage; SO realdir mirrordir" unless ©ARGV == 2; for ((Ssrcdir, Sdstdir) = @ARGV) { my Sis dir = -d; next if $is dir; # Нормально if (defined ($is dir)) { die "SO; S is not a directory\n"; 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 |