Рекурсивное копирование файлов, соответствующих шаблону - PullRequest
0 голосов
/ 05 марта 2019

Я собрал скрипт, который рекурсивно копирует из одного каталога в другой, пропуская файлы с определенным шаблоном в имени файла:

function Copy-RevitFiles ([string]$source, [string]$destination, [boolean]$recurse) {

    $pattern = '\.\d\d\d\d\.[RVT]'

    if ($recurse) {$files = Get-ChildItem $source -Recurse}
    else {$files = Get-ChildItem $source}


    $files | ForEach-Object {
    if ((Select-String -InputObject $_.Name -pattern $pattern -AllMatches -quiet) -eq $null) {
        #Write-Host $_.Name
        #Write-Host $_.Fullname
        #Write-Host "$($destination)\$($_.FullName.TrimStart($source))"
        Copy-Item $_.FullName -Destination "$($destination)\$($_.FullName.TrimStart($source))" #add on full name of item, less $source start end of file path
        #Write-Host "----------"
        }
    }
}

В большинстве случаев он работает хорошо.Однако у меня проблема в том, что внутри каждой папки создается дополнительная подпапка с файлами в ней.Например:

Если ввести источник как каталог с такой структурой:

Source
-file1.rvt
-file1.0225.rvt (will not copy as it matches the pattern)
-file1.0226.rvt (will not copy as it matches the pattern)
-folder1
 |-file2.rvt
 |-file2.0121.rvt (will not copy as it matches the pattern)
 |-file2.0122.rvt (will not copy as it matches the pattern)
-folder2

Я ожидаю, что в целевой папке будет создана следующая структура:

Destination
-file1.rvt
-folder1
 |-file2.rvt
-folder2

Но вместо этого я получаю:

Destination
-file1.rvt
-folder1
 |-file2.rvt
 |-folder1 (extra folder not in source)
-folder2

Есть идеи, где я ошибаюсь?

1 Ответ

0 голосов
/ 05 марта 2019

Это способ создания конечного пункта, а также способ обработки возвращенного значения для командлета Select-STring с параметром -Quiet.
При использовании переключателя Quiet командлет вернет логическое значение ($ trueили $ false), но вы проверяете на равенство $null.

Если я использую командлет Join-Path (вместе с некоторыми другими настройками вашей функции), например:

function Copy-RevitFiles {
    [CmdletBinding()]
    Param(
        [string]$source, 
        [string]$destination,
        [string]$pattern, 
        [switch]$recurse
    )

    # test if the destination folder exists
    if (!(Test-Path -Path $destination -PathType Container)) {
        New-Item -ItemType Directory -Path $destination -Force | Out-Null
    }

    $files = Get-ChildItem $source -Recurse:$recurse

    $files | ForEach-Object {
    if (!(Select-String -InputObject $_.Name -Pattern $pattern -AllMatches -Quiet)) {
        #Write-Host $_.Name
        #Write-Host $_.Fullname
        $target = Join-Path -Path $destination -ChildPath $_.Fullname.TrimStart($source)
        #Write-Host "Copying '$_.Fullname' to '$target'" 
        $_ | Copy-Item -Destination $target
        #Write-Host "----------"
        }
    }
}

и используйте его в соответствии с вашим Source примером:

Copy-RevitFiles -source "D:\Source" -destination "D:\Destination" -pattern '\.\d\d\d\d\.[RVT]' -recurse

Это приведет к:

Destination
|   file1.rvt
|
+---folder1
|       file2.rvt
|
\---folder2
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...