PERL: БИБЛИОТЕКА ПРОГРАММИСТА


PERL: БИБЛИОТЕКА ПРОГРАММИСТА - стр. 168


Программа получается рекурсивной, поскольку рекурсивна сама файловая си­стема. Однако ее структуры данных не рекурсивны — по крайней мере, не в том смысле, в котором рекурсивны циклические связанные списки. Каждое ассоции­рованное значение представляет собой массив ключей для дальнейшей обработ­ки. Рекурсия заключается в обработке, а не в способе хранения.

Пример 5.3. dutree

#'/usr/bin/perl -w

#  dutree - печать сортированного иерархического представления

#  выходных данных du
use strict,

my %Dirsize, my %Kids,

getdots(my $topdir = mput()), output($topdir),

#  Запустить du, прочитать входные данные, сохранить размеры и подкаталоги

#  Вернуть последний прочитанный каталог (файл9)
sub input {

™y($size, $name, Sparent),

@ARGV = ( du @ARGV | ),       fl Подготовить аргументы

while (о)

(Ssize, $name) = split,

$Dirsize{$name} = $size,

(Sparent = $name) =' s#/["/]+$#»,  fl Имя каталога

push @{ $Kids{$parent} }, $name unless eof, > return $name;

fl Рассчитать,   сколько места занимают файлы каждого каталога,

#   не находящиеся в подкаталогах   Добавить новый фиктивный

#   подкаталог с именем '   ',   содержащий полученную величину
sub getdots  {

продолжение


176   Глава 5 • Хэши

Пример 5.3 (продолжение)

my $root = $_[0],

my($size, $cursize),

$size = Scursize = $Dirsize{$root},

if \$Kids<$root}) {

for my $kid (@{ $ Kids {$ root} }) {

$cursize -= $Dirsize{$kid},

getdots($kid),

if ($size •= $cursize) { my $dot = $root/ , $Dirsize{$dot} = $cursize, push @{ $Kids{$root} }, $dot,

ft Рекурсивно вывести все данные,

# передавая при рекурсивных вызовах

#   выравнивающие пробелы и ширину числа
sub output {

my($root, Sprefix, $width) = (shift, shift || ", shift || 0),

my $path,

($path = $root) =" s# */##,    # Базовое имя

my $size = $Dirsize{$root},

my $line = spnntf( %${width}d %s', Ssize, $path),

print Sprefix, $lme, \n',

for ($prefix = $line) {     # Дополнительный вывод




- Начало -  - Назад -  - Вперед -