вторник, февраля 17, 2009

Perl - перемещение файлов по подкаталогам

Сегодня, думаю запощу сразу два поста. "Запощу пост"... Мда, новые времена - повые тафтологии.


Первое обращение посвящено тем кто хочет посмотреть для чего можно использовать Perl. Недавно начал смотреть что это за язык такой. Должен сказать - впечатляет. Условный оператор unless, модификаторы операторов... Весьма, весьма.


Но перейдём к делу. Была у меня папка в которой лежало весьма приличное количество файлов - 6700+ штук. И все они лежали в одной папке. То что это не нравилось наутилусу - мягко сказано. Решил раскидать файлы по подкаталогам. Причём так что имя подкаталога должно начинаться с порядкового номера файла, потом дефис и порядковый номер последнего файла. Все эти "порядковые номера", естественно, относительно их изначальной индексации в каталоге.


Сначала попытался сделать это в ручную... А потом понял что это прекрасное поле для того что бы опробовать то что я узнал из самоучителей. К тому же, как в них, в самоучителях, зная минимум можно делать весьма впечатляющие вещи. Собственно в этом я и убедился.


А теперь собственно сам код. Так как он обильно снабжён комментариями, то думаю мои дальнейшие разглагольствования будут не уместны.


Одно малюсенькое змечание - код писался в Vim, а затем с помощью же Vim'а экспортировался в HTML.



#!/usr/bin/perl
use strict;
use warnings;
my @files;
# открываем директорию
opendir(my $sdir, '.') or die($!);
# и считываем все файлы исключая файл-скрипт в массив
@files = grep { -f && !/move_files\.pl/} readdir $sdir;
&move_file(\@files);
# этим будем двигать файлы
sub move_file() {
  # номер итерации
  my $n = 0;
  # количество перемещаемых файлов
  my $offset = 128;
  # получаем ссылку на массив с файлами
  my $files = shift;
  # обходим массив с файлами, передвигаясь на число перемещаемых файлов
  for (my $i=0; $i<$#{$files}; $i+=$offset, $n++) {
    # начальный индекс для среза - ниндекс
    my $start = $n*$offset;
    # конечный индекс для среза - киндекс
    # если вычисляемый киндекс больше последнего индекса, то устанавливаем киндекс на последний элемент,
    # в противном случае используем вычисляемый киндекс
    my $end = (($start+$offset-1)>$#{$files)?($#{$files}):$start+$offset-1;
    # делаем срез для массива файлов
    my @move = @$files[$start..$end];
    # создаём директорию куда переместим файлы
    my $dir = sprintf("%03d-%03d", $start, $end);
    mkdir($dir, 0766) or die($!);
    # переименовываем каждый элемент
    foreach (@move) {
      rename($_, $dir.'/'.$_) or die($!);
    }
  }
}

Комментариев нет:

Отправить комментарий