Как определить следующий номер для присвоения файла при попытке организовать каталог? - PullRequest
0 голосов
/ 29 июня 2011

Я работаю над сценарием perl, чтобы организовать имеющуюся папку, в которой хранятся все наши документы заказа.Сценарий работает по большей части, за исключением кривого шара, который кто-то бросил мне на днях.

Проблема в том, что у нас есть заказ, который мы недавно переделали.Мы являемся геодезистами, и иногда мы проводим съемку, а затем через несколько лет мы будем делать то, что называется «облетом», куда мы вернемся и «добавим» заказ в другой файл, либо отметив изменения в земле, либо простоскажем, что все в порядке и ничего не изменилось.

Для меня проблема заключается в том, что новый файл, который мы создаем / изготавливаем, имеет тот же номер документа заказа, что и старый документ.Например, у нас может быть документ с именем CF145323, тогда в этом документе будет несколько одностраничных PDF-файлов с именем CF145323.pdf, * _1.pdf, * _2.pdf и т. Д.

Что я ищу, так этоспособ изменить мой скрипт для подсчета найденных файлов и определения / прогнозирования следующего номера файла.Так что, если был * _1.pdf через * _3.pdf.Я хочу, чтобы Perl взял несоответствующий файл и сделал его * _4.pdf.Следуйте за мной?

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

Также я работаю в Windows, поэтому не могу использовать какие-либо команды Linux.

Вот мой сценарийв последнем состоянии я оставил его:

#!/usr/bin/perl
use strict;
use warnings;

# Root folder for Order Documents
my $orders_root = "C:\\Users\\Ian\\Desktop\\Order_docs";

# Keep track of how many files are processed
my $files_counter = 0;

# Keep track of how many junk files are processed
my $junk_counter = 0;

# Store a list of folders that match the 3 number naming scheme
my @matched_folders;

# Create a place to move junk files into
if (! -e "$orders_root\\Junk") {

    system "mkdir $orders_root\\Junk";

}

# Clear the screen
system "cls";

print "Processing files, please wait...\n\n";

# Open $order_dir_root
opendir(ORDERS_ROOT, "$orders_root") or die $!;

# Collect a list of all sub folders
my @folders = readdir(ORDERS_ROOT);

# Close $order_dir_root 
closedir(ORDERS_ROOT);

# Remove the directories "." and ".." from the output
splice @folders, 0, 2;

foreach my $folder (@folders) {

    # Filter out all directories that don't match the numbering system
    if ($folder =~ / \d{3} /xm) {

        # If the folder matches the expression above, add it to the list of matched folders
        push @matched_folders, $folder;

        # Open each folder inside of the Order Documents root
        opendir(CURRENT_FOLDER, "$orders_root\\$folder");

        # Foreach folder opened, collect a list of files in the folder for sorting
        my @files = readdir(CURRENT_FOLDER);

        # Close the current folder
        closedir(CURRENT_FOLDER);

        # Remove the directories "." and ".." from the output
        splice @files, 0, 2;

        foreach my $file (@files) {

            # Match each file to the standard naming scheme
            if ($file =~ /^ (C[AFL]|ME) \d{3} \d{3}([_|\-] \d+)? \. pdf /xmi) {

                ++$files_counter;

            # If that file does not match, move it to a junk folder
            } else {

                ++$junk_counter;

                rename ("$orders_root\\$folder\\$file", "$orders_root\\Junk\\$file");

            } # End pdf match           

        } # End foreach $file

    } # End folder match

} # End foreach $folder



foreach my $folder (@matched_folders) {

    # Open $folder
    opendir(CURRENT_FOLDER, "$orders_root\\$folder");

    # Collect a list of all sub folders
    my @files = readdir(CURRENT_FOLDER);

    # Close $folder
    closedir(CURRENT_FOLDER);

    splice @files, 0, 2;

    foreach my $file (@files) {

        if ($file =~ /^ (?<office> (C[AFL]|ME)) (?<folder_num> \d{3}) (?<file_num> \d{3}([_|\-] \d+)?) \. (?<file_ext> pdf) /xmi) {

            my $office = uc($+{office});
            my $folder_num = $+{folder_num};
            my $file_num = $+{file_num};
            my $file_ext = lc($+{file_ext});

            # Change hyphens to a underscore
            $file_num =~ s/\-/_/;

            my $file_name = "$office" . "$folder_num" . "$file_num" . "\." . "$file_ext";
            my $fly_by_name = "$office" . "$folder_num" . "$file_num" . "_FB" . "\." . "$file_ext";

            # Check if the current file belongs in the current folder
            if ($folder != $folder_num) {

                # If the folder does not exist create the folder
                if (! -e "$orders_root\\$folder_num") {

                    system "mkdir $orders_root\\$folder_num";

                }

                # Check to see if the file already exists
                if (! -e "$orders_root\\$folder_num\\$file_name") {

                    # Moves the file to correct place, these are mismatched files
                    rename ("$orders_root\\$folder\\$file", "$orders_root\\$folder_num\\$file_name");

                } else {

                    # Appends the file with a "_#" where # is equal to the 1+ the last file number, these files are fly bys
                    rename ("$orders_root\\$folder\\$file", "$orders_root\\$folder_num\\$fly_by_name");

                }

            # Files are in the correct place, the file name will be corrected only
            } else {

                rename ("$orders_root\\$folder\\$file", "$orders_root\\$folder_num\\$file_name");

            }

        } # End $file match

    } # End foreach $file

} # End foreach $folder



# Show statistics after processing
print "Done!\n\n";
print "$#folders folders processed\n";
print "$files_counter files processed\n";
print "$junk_counter junk files removed\n"

1 Ответ

1 голос
/ 29 июня 2011

Ваш сценарий довольно большой, чтобы пробираться через него, но я предлагаю другой подход.

Первое, и самое очевидное, это что-то вроде этого:

my $base = "CF145323";
my $num = 1;
$num++ while -f "${base}_$num.pdf";

my $filename = "${base}_$num.pdf";
print "$filename\n";

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

Может быть проще вести учет каждого файла и его последнего поколения. Как правило, это будет хеш, используя, например, «CF145323» в качестве ключа и номер последней версии в качестве значения. Хеш может быть сохранен и восстановлен с помощью модуля Storable (очень прост в использовании и в базе Perl).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...