По долгу службы работаю также с подрядчиками нашего производства. Естественно, передавать им изменения в документации бумагами накладно, а в некоторых случаях – недопустимо (подрядчики есть и за 200, и за 800 км). Поэтому озаботился вопросом создания некоего централизованного хранилища чертежей (уже в общеупотребимом виде (.tif, .xps)) и прочих технических документов и для себя, и для подрядчиков. Для этих целей выбрал Subversion + TortoiseSVN + PowerShell.

О TortoiseSVN и о создании репозитория уже писал, повторяться не буду. Задача для данной статьи крайне простая:

  1. Раскладываем файлы по папкам (PoSh) (готовим структуру электронного архива) Имею папку, в которой уже лежат файлы следующего вида: XXXX.XX.XX.XXX.tif (.mdi), где X – децимальный номер документа в соответствии с ЕСКД. Сам файл, как уже понятно, содержит “картинку” чертежа или другого документа, определяющего требования к детали / узлу.
  2. Учитывая тот факт, что в некоторых случаях требования могут определяться не одним документом, а несколькими, решил всё-таки разложить указанные файлы по подпапками вида. Например, для файла К309.01.02.009.tif создаём иерархию папок К309\01\02\009\_self, куда уже и выкладываем все файлы для указанной детали.

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

<#
    .Synopsis
        Раскладываем файлы по подпапкам.
    .Description
        Получает на вход либо объект, либо путь к папке, содержащей файлы.
        Создаёт подпапки в папке (второй аргумент, если не указан, то подпапки
        создаются в исходной папке) с именами, совпадающими с именами файлов
        (без учёта расширения). Файлы переносит в созданные подпапки.
    .Parameter sourceFolder
        Каталог, файлы которого будут обработаны
    .Parameter destFolder
        Каталог, в котором будет создана требуемая структура
    .Parameter searchPattern
        Маска для поиска файлов.
    .Parameter splitter
        Символы - разделители в имени файла для выделения дочерних папок.
    .Example
        Раскладываем файлы по папкам "на месте", в исходной папке.

        .\FilesToFolder.ps1 "X:\Порталы\Аутсорсинг\Процессы\Гальванические покрытия\Чертежи"
#>
 
param (
    [Parameter(
        Mandatory=$true,
        Position=0,
        ValueFromPipeline=$true,
        HelpMessage="Source folder."
    )]
    [System.IO.DirectoryInfo]
    $sourceFolder,
    [Parameter(
        Mandatory=$false,
        Position=1,
        ValueFromPipeline=$false,
        HelpMessage="Destination folder."
    )]
    [System.IO.DirectoryInfo]
    $destFolder = "c:\temp\test22",
       [Parameter(
        Mandatory=$false,
        Position=2,
        ValueFromPipeline=$false,
        HelpMessage="File mask."
    )]
    [string]
    $searchPattern = '*.*',
       [Parameter(
        Mandatory=$false,
        Position=3,
        ValueFromPipeline=$false,
        HelpMessage="File name splitter."
    )]
    [string]
    $splitter = '\.|-'
)

$files = @(get-childItem `
    -path $sourceFolder `
    -filter $searchPattern `
);
$files | % `
    -begin {
        [int]$fileIndex = 0;
        write-progress `
            -id 1 `
            -activity 'Переносим файлы в древовидную структуру папок' `
            -status 'Приступаем...'
     } `
    -process {
        copy-item `
            -path ($_.FullName) `
            -destination ( `
                new-item `
                    -path (
                        (([System.IO.Path]::GetFileNameWithoutExtension($_.Name)) -split $splitter) `
                        | % `
                            -begin   { [string]$newSubFolder = $destFolder; } `
                            -process { $newSubFolder = join-path -path $newSubFolder -childPath $_; } `
                            -end     { $newSubFolder }
                    ) `
                    -type directory `
                    -force
            )
        $fileIndex++;
        write-progress `
            -id 1 `
            -activity 'Переносим файлы в древовидную структуру папок' `
            -status 'Переносим файлы' `
            -currentOperation "$($_.Name) ($($fileIndex) из $($files.count))" `
            -percentcomplete ($fileIndex/$files.count*100)
    } `
    -end {
        write-progress `
            -id 1 `
            -activity 'Переносим файлы в древовидную структуру папок' `
            -status 'Завершили...' `
            -completed
    }

Раскладываем файлы по папкам (PoSh) (готовим структуру электронного архива)Как видно, мы прицепили к сценарию и прогресс-бар (советую).

Раскладываем файлы по папкам (PoSh) (готовим структуру электронного архива)В результате выполнения сценария получаем иерархическую систему папок со скопированными в неё исходными файлами (на рисунке слева).

P.S. Совершенно справедливо можно подметить, довольно громоздкую конструкцию можно было бы заменить банальной заменой . в имени файла на \ одним оператором. Но я сознательно нарисовал код с использованием join-path с тем, чтобы кросс-платформенным, и не зависел от провайдера (теоретически, этот сценарий будет прекрасно работать не только для файловой системы).

P.P.S. Также должен обратить внимание на тот факт, что отображённый на картинке результат не совсем соответствует результату работы выше приведённого сценария. Сценарию был задан параметр –splitter '(Э)|(СТС)|(СТМ)|(СТН)|(ЛТК)|(КАД)|(Л)|(ШМГ)|(К)|(А)|(?:[\.|-])' (так как в моём случае не все элементы группировки файлов явным образом выделены разделителями в имени файла). Подробнее подобное применение оператора –split рассматриваю в отдельной статье.

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

XHTML: Вы можете использовать следующие HTML теги: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Tags Связь с комментариями статьи:
RSS комментарии
Обратная ссылка