Анимация
JavaScript
|
Главная Библионтека Глава 13 Манипулирование файлами и каталогами " 1. Вот один из способов решения этой задачи: unlink @ARGV; Да, именно так. Массив @argv - это список имен, подлежащих удалению. Операция unlink получает список имен, поэтому нам нужно лишь соединить два этих компонента, и дело сделано. Конечно, здесь не реализован ни механизм уведомления об ошибках, ни опции - f и -1, ни другие подобные вещи, но это было бы уже слишком серьезно. Если вы это сделали - отлично! 2. Вот один из способов решения этой задачи: ($old, $new) = gARGV; # назвать их if (-d Snew) { # новое имя - каталог, его нужно откорректировать ($basename = $old) =~ s#.*/##s; # получить название собствеино # каталога $old $new .= "/$basename"; # и добавить его к новому имени rename($old,$new) I die "Cannot rename $old to $new: S"; Рабочая лошадка в этой программе - последняя строка, но все остальное тоже нужно на тот случай, если новое имя принадлежит каталогу. Сначала мы даем наглядные имена двум элементам массива SARGV. Затем, если имя $new - каталог, нам нужно откорректировать его, добавив в конец нового имени собственно имя каталога $old. Это значит, что переименование /usr/src/fred в /etc фактически приводит к переименованию /usr/src/fred в /etc/fred. Наконец, после добавления собственно имени каталога мы завершаем задачу вызовом rename. 3. Вот один из способов решения этой задачи: ($old, $new) = @ARGV; # назвать их if (-d $new) { # новое имя - каталог, его нужно откорректировать ($basename = $old) =~ s#.*/##s; # получить название собственно # каталога $old $new .= "/$basename"; # и добавить его к новому имени link($old,$new) I I die "Cannot link $old to $new: $"; Эта программа идентична предыдущей программе за исключением самой последней строки, потому что мы создаем ссылку, а не выполняем переименование. 4. Вот один из способов решения этой задачи: if ($ARGV[0] eq "-s") ( # нужна символическая ссылка 5symlink++; # запомнить shift(@ARGV); # и отбросить флаг -s ($old, $new) = @ARGV; # назвать их if (-d $new) ( # новое имя - каталог, его нужно откорректировать ($basename = $old) =~ s#.*/##s; # получить название собственно # каталога $old $new .= "/$basename"; # и добавить его к новому имени if ($symlink) { # wants а symlink symlink($old,$new); ] else ( # нужна жесткая ссылка link($old,$new); Средняя часть этой программы - такая же, как в предыдущих двух упражнениях. Новые здесь - несколько первых и несколько последних строк. В первых строках осуществляется проверка первого аргумента программы. Если этот аргумент равен -s, то скалярная переменная $symlink инкрементируется, получая в результате значение 1. Затем выполняется сдвиг массива @argv, в результате чего удаляется флаг -s. Если флаг -s отсутствует, то ничего не делается и $symlink остается равной undef. Сдвиг массива @argv выполняется достаточно часто, поэтому имя массива @argv является аргументом функции shift по умолчанию; то есть вместо shift(@ARGV); МЫ могли бы написать shift; Последние несколько строк проверяют значение $ symlink. Оно будет равно либо 1, либо undef, и на основании этого для файлов выполняется либо операция symlmk, либо link. 5. Вот один из способов решения этой задачи: foreach $f (<*>) { print "$f -> $where\n" if defined($where = readlink($f)); Скалярной переменной $f присваивается по очереди каждое из имен файлов текущего каталога. Для каждого имени переменной $ where присваивается значение, полученное в результате выполнения функции readlink () ДЛЯ данного имени. Если имя - не символическая ссылка, то операция readlink возвращает undef, давая значение "ложь" в проверке if, а print пропускается. Если же операция readlink возвращает какое-то значение, то print выводит название символической ссьшки и имя файла или директории, на которую она указывает. Глава 14 Управление процессами 1 Вот один из способов рещения этой задачи: if ( date =~ /"S/) { print "Go play\n"; 1 else ( print "Get to work\n"; Оказывается, команда date выводит букву s в качестве первого символа только по выходным (Sat или Sun), что делает задачу тривиальной. Мы вызываем date, затем с помощью регулярного выражения смотрим, является ли первый символ буквой S. На основании результата мы выводим одно сообщение или другое. 2 Вот один из способов рещения этой задачи: open(PW,"/etc/passwd"); while (<PW>) ( chomp, ($user,$gcos) = (split /:/)[0,4]; ($real) = split(/,/, $gcos); $reaH$user) = $real; close(PW), open(WHO,"who I") die "cannot open who pipe"; while (<WH0>) ( ($login, $rest) = /-(\S+) \s+(. *)/; Slogin = $reaH$login) if $reaH $login); printf "%-30s %s\n",$login, $rest, В первом цикле создается хещ %real, ключи которого - регистрационные имена, а значения - соответствующие реальные имена. Этот хещ используется в следующем цикле для замены регистрационного имени на реальное. Во втором цикле осуществляется просмотр результата вьшолнения команды who, которая вызвана при помощи дескриптора файла. Каждая строка полученного в результате выражения разбивается путем сопоставления с регулярным выражением в списочном контексте. Первое слово строки (регистрационное имя) заменяется реальным именем из хеща, но только если оно существует. После всего этого с помощью функции printf результат помещается в stdout. 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 |