3

Я хотел бы найти и скопировать все файлы в определенном каталоге и все его подкаталоги с определенным именем.

Я использую Copy-Item в Powershell (TechNet | ss64)

Вот что у меня есть:

Copy-Item `
    -Path \\Server\Apps\* `
    -Destination C:\ReadMeFiles\ `
    -Include *ReadMe.txt `
    -Recurse `
    -WhatIf

Будет загружен следующий файл:

\\Server\Apps\ReadMe.txt

Но нет:

\\Server\Apps\AppName\ReadMe.txt

Даже если я указал -recurse

Как я могу заставить его путешествовать вниз в каждом каталоге?

2 ответа2

4

Это известная проблема с Copy-Item, вы не можете указать подстановочный знак в источнике и использовать Recurse (и заставить его работать так, как вы ожидаете).

Если вы не против скопировать структуру папок (но только копировать файлы readme), попробуйте использовать параметр "Фильтр". Что-то вроде:

Copy-Item \\Server\Apps\ C:\ReadMeFiles\ -Filter *ReadMe.txt -Recurse

В качестве альтернативы вы можете использовать Get-Child-Item с Recurse и цикл For для подачи файлов Copy-Item по одному.

3

Мой слегка измененный ответ на этот вопрос: Пакетный файл: Перечислите все файлы типа, переименуйте файлы, распрямите каталог

Он делает то, что вам нужно: копирует файлы с использованием подстановочных знаков, выравнивает структуру каталогов, обрабатывает конфликты имен файлов. Он использует Get-ChildItem , как предложил Tᴇcʜιᴇ007 .

# Setup source and destination paths
$Src = '\\Server\Apps'
$Dst = 'C:\ReadMeFiles'

# Wildcard for filter
$Extension = '*ReadMe.txt'

# Get file objects recursively
Get-ChildItem -Path $Src -Filter $Extension -Recurse |
    # Skip directories, because XXXReadMe.txt is a valid directory name
    Where-Object {!$_.PsIsContainer} |
        # For each file
        ForEach-Object {

            # If file exist in destination folder, rename it with directory tag
            if(Test-Path -Path (Join-Path -Path $Dst -ChildPath $_.Name))
            {
                # Get full path to the file without drive letter and replace `\` with '-'
                # [regex]::Escape is needed because -replace uses regex, so we should escape '\'
                $NameWithDirTag = (Split-Path -Path $_.FullName -NoQualifier)  -replace [regex]::Escape('\'), '-'

                # Join new file name with destination directory
                $NewPath = Join-Path -Path $Dst -ChildPath $NameWithDirTag
            }
            # Don't modify new file path, if file doesn't exist in target dir
            else
            {
                $NewPath = $Dst
            }

            # Copy file
            Copy-Item -Path $_.FullName -Destination $NewPath
        }

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .