# Пропустить . и ..

  next if ['.','..'].include? e

  fullname = src + '/' + e

  newname = fullname.sub(Regexp.new(Regexp.escape(src)),dst)

  if FileTest:rdirectory?(fullname)

   recurse(fullname,newname)

  elsif FileTest::symlink?(fullname)

   linkname = 'ls -l #{fullname}'.sub(/.* -> /,'').chomp

   newlink = linkname.dup

   n = newlink.index($oldname)

   next if n == nil

   n2 = n + $oldname.length - 1

   newlink[n..n2] = $newname

   newlink.sub!(////,'/')

   # newlink = linkname.sub(Regexp.new(Regexp.escape(src)),dst)

   File.symlink(newlink, newname)

  elsif FileTest::file?(fullname)

   FileUtils.copy(fullname, newname)

  else

   puts '??? : #{fullname}'

  end

 end

end

# 'Главная программа'

if ARGV.size != 2

 puts 'Usage: copytree oldname newname'

 exit

end

oldname = ARGV[0]

newname = ARGV[1]

if ! FileTest::directory?(oldname)

 puts 'Ошибка: первый параметр должен быть именем существующего каталога.'

 exit

end

if FileTest::exist? (newname)

 puts 'Ошибка: #{newname} уже существует.'

 exit

end

oldname = File.expand_path(oldname)

newname = File.expand_path(newname)

$оldname=oldname

$newname=newname

recurse(oldname, newname)

Возможно, и существуют варианты UNIX, в которых команда cp -R сохраняет символические ссылки, но нам о них ничего не известно. Программа, показанная в листинге 14.5, была написана для решения этой практической задачи.

14.8.3. Удаление файлов по времени модификации и другим критериям

Предположим, вы хотите удалить самые старые файлы из какого-то каталога. В нем могут, к примеру, храниться временные файлы, протоколы, кэш браузера и т.п.

Ниже представлена небольшая программа, удаляющая файлы, которые в последний раз модифицировались раньше указанного момента (заданного в виде объекта Time):

def delete_older(dir, time)

 Dir.chdir(dir) do

  Dir.foreach('.') do |entry|

   # Каталоги не обрабатываются.

   next if File.stat(entry).directory?

   # Используем время модификации.

   if File.mtime(entry) < time

    File.unlink(entry)

   end

  end

 end

end

delete_older('/tmp',Time.local(2001,3,29,18,38,0))

Неплохо, но можно обобщить. Создадим метод delete_if, который принимает блок, возвращающий значение true или false. И будем удалять те и только те файлы, которые удовлетворяют заданному критерию.

def delete_if(dir)

 Dir.chdir(dir) do

  Dir.foreach('.') do |entry|

   # Каталоги не обрабатываются.

   next if File.stat(entry).directory?

   if yield entry

    File.unlink(entry)

   end

  end

 end

end

# Удалить файлы длиннее 3000 байтов.

delete_if('/tmp') { |f| File.size(f) > 3000 }

# Удалить файлы с расширениями LOG и BAK.

delete_if('/tmp') { |f| f =~ /(log|bak)$/i }

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату