2016-07-28 3 views
0

Я работаю над машиной Windows, и у меня есть каталог, заполненный ~ 200 тыс. Файлов, которые мне нужно организовать. Это задание, которое мне нужно будет делать регулярно с разными наборами файлов, но с похожими шаблонами, поэтому perl казался хорошим инструментом для использования.Организация файлов в окнах с использованием perl

Каждое имя файла состоит из {струнный A} {2 или 3 значное число B} {одной буквой "г" или "х"} {3} значное число .extension

Я хочу, чтобы создать папка для каждой строки

в каждой папке я хочу вложенную папку для каждого B

затем я хочу, чтобы переместить каждый файл в его соответствующую подпапку

Так это будет в конечном итоге выгляжу что-то вроде

/CustomerA/1 
/CustomerA/2 
/CustomerA/3 
/CustomerB/1 
/CustomerB/2 
/CustomerB/3 

и т.д. с файлами в каждой подпапке

так CustomerA888x123.xml перемещается в/customerÃ/888/

У меня есть список файлов в массив, но я борюсь с расщеплением вывести имя файла в его составные части и эффективно использовать детали.

Спасибо за ответ. Я закончил с этим:

#!usr/bin/perl 
use warnings; 
use strict; 
use File::Copy qw(move); 
use File::Path qw(make_path); 

opendir my $dir, "."; 
my @files = readdir($dir); 
closedir $dir; 

foreach my $file (@files) { 
    my ($cust, $num) = $file =~ m/(\D+)(\d+)/; 
    my $dirname = "$cust/$num"; 
    my @dirs_made = make_path($dirname, { verbose => 1 }); 
    move($file, $dirname) or warn "cant move $file to $dirname: $!"; 
} 
+2

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

+0

Я редактировал код в вашем вопросе, чтобы добавить некоторые отступы и пустые строки для удобства чтения. Если вам это не нравится, пожалуйста, отбросьте его обратно - нажмите «_edited ..._» (над именем пользователя), а затем нажмите «_rollback_» в предыдущей версии. – zdim

+0

это здорово, спасибо. В коде, который я написал, есть пустые строки и больший отступ, но когда я вставлял его в качестве комментария, форматирование получило немного грушевидной формы, поэтому я удалил пустые строки, думая, что это вызывает проблемы с форматированием. Снова, большое спасибо. – Steve

ответ

3

Учитывая ваше описание имен файлов, это регулярное выражение следует разобрать, что вам нужно

my ($cust, $num) = $filename =~ m/(\D+)(\d+)/; 

Используйте более точный шаблон, если вы хотите или должны быть более конкретными о том, что предшествует номеру, например, [a-zA-Z] только для букв.

С, что под рукой, вы можете создавать каталоги, используя модуль ядра File::Path, например

use File::Path qw(make_path); 
my $dirname = "$cust/$num"; 
my @dirs_made = make_path($dirname, { verbose => 1 }); 

Это создает путь по мере необходимости, возвращая имена созданных каталогов. Он также печатает имена с verbose. Если каталог существует, он спокойно пропускает его. Если есть проблемы, которые она поднимает die, так что вы можете обернуть его в eval

eval { make_path($dirname) }; 
if ([email protected]) { 
    warn "Error with make_path($dirname): [email protected]"; 
} 

Также обратите внимание на модуль File::Path::Tiny в качестве альтернативы, благодаря Sinan Ünür для приведения его. Кроме того, что гораздо легче, он также имеет более общий обработки ошибок политику, при которой ложная возвращается на провал, так что вам не нужен eval, но только обычную проверку

use File::Path::Tiny; 
File::Path::Tiny::mk($path) or warn "Can't mk($path): $!"; 

Модуль ведет себя так же, как в mkdir многие способы, см. связанную документацию.

Перемещение файлов с помощью функции move образуют модуль ядра File::Copy, например

use File::Copy qw(move); 
move($file, $dirname) or warn "Can't move $file to $dirname: $!"; 

Все это может быть в цикле по массиву с именами файлов.

+0

Действительно ли 'make_path' действительно умирает при неудаче? – Borodin

+0

@ Бородин Да, я так считаю. Я всегда 'eval' это, и я пробовал на cmdline сейчас. – zdim

+0

В чем причина неудачи? – Borodin

Смежные вопросы