Рекурсивно скопировать набор файлов из одного каталога в другой в PowerShell

Я пытаюсь скопировать все *.csproj.user файлы рекурсивно из C:\Code\Trunk в C:\Code\F2.

Например:

C:\Code\Trunk\SomeProject\Blah\Blah.csproj.user

Скопировал бы:

C:\Code\F2\SomeProject\Blah\Blah.csproj.user

Моя текущая попытка:

Копировать-элемент C:\Code\Trunk -Filter *.csproj.user -Destination C:\Code\F2 -Recurse -WhatIf

Однако я получаю:

Что делать, если: Выполнение операции "Копировать каталог" на целевом элементе: C:\Code\Trunk Destination: C:\Code\F2\Trunk ".

Во-первых, он хочет поместить все их в новую папку с именем F2\Trunk, что неверно. Во-вторых, он не перечисляет ни один из файлов. Должно быть скопировано около 10 файлов.

Какой правильный синтаксис для команды? Спасибо!

Update:

Хорошо, похоже, что это связано с тем, что C:\Code\F2 уже существует. Если я попытаюсь скопировать файлы в место назначения, которое не существует, оно работает.

Я хочу перезаписать все существующие файлы .csproj.user в пункте назначения.

Ответ 1

Видел это раньше, и я не знаю, почему PowerShell не может показаться правильным (IMHO). То, что я сделаю, более громоздко, но оно работает.

$Source = 'C:\Code\Trunk'
$Files = '*.csproj.user'
$Dest = 'C:\Code\F2'
Get-ChildItem $Source -Filter $Files -Recurse | ForEach{
    $Path = ($_.DirectoryName + "\") -Replace [Regex]::Escape($Source), $Dest
    If(!(Test-Path $Path)){New-Item -ItemType Directory -Path $Path -Force | Out-Null
    Copy-Item $_.FullName -Destination $Path -Force
}

Ответ 2

Вы, ребята, делаете это ужасно сложным, когда это действительно просто:

Copy-Item C:\Code\Trunk -Filter *.csproj.user -Destination C:\Code\F2 -Recurse

Скопирует Каталог, создав в F2 каталог "Trunk". Если вы хотите избежать создания папки Trunk верхнего уровня, вам нужно прекратить сообщать PowerShell о ее копировании:

Get-ChildItem C:\Code\Trunk | Copy -Destination C:\Code\F2 -Recurse -filter *.csproj.user

Ответ 3

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

robocopy C:\Code\Trunk C:\Code\F2 *.cs *.xaml *.csproj *.appxmanifest /s

Ответ 4

Ответ 1 выглядел хорошо, и я изменил его на Move-Item для моих целей. Однако я обнаружил, что в каждой папке он рекурсивно прошел, он только переместил первый файл. Ниже приведена моя полная script, которая также включает в себя некоторую конверсию файлов doc в pdf:

$Source = 'C:\Users\sgrody\Desktop\NSPM-Vol1'
$MoveFiles = '*.PDF'
$Dest = 'C:\Users\sgrody\Desktop\MedPassPDF'
$Folders = Get-ChildItem $Source -Directory -Recurse 


ForEach ($Folder in $Folders)
{
    $wdFormatPDF = 17
    $word = New-Object -ComObject word.application
    $word.visible = $false
    $folderpath = "$($Folder.FullName)\*"
    $fileTypes = "*.docx","*doc"
    Get-ChildItem -path $folderpath -include $fileTypes |
    foreach-object 
    {
     $path =  ($_.fullname).substring(0,($_.FullName).lastindexOf("."))
     "Converting $path to pdf ..."
     $doc = $word.documents.open($_.fullname)
     $doc.saveas([ref] $path, [ref]$wdFormatPDF)
     $doc.close()
    }
    $word.Quit()
}

Get-ChildItem $Source -Filter $MoveFiles -Recurse | ForEach{
    $Path = ($_.DirectoryName + "\") -Replace [Regex]::Escape($Source), $Dest
    If(!(Test-Path $Path)){New-Item -ItemType Directory -Path $Path -Force | Out-Null
    Move-Item $_.FullName -Destination $Path -Force
    }
}

Ответ 5

Я попробовал ответить Jaykul, и это не сработало для меня. Мне пришлось изменить его, как показано ниже, чтобы заставить его работать. Я также создал папку C:\Code\F2, прежде чем она сработает.

Get-ChildItem C:\Code\Trunk Recurse -filter *.csproj.user | Copy -Destination C:\Code\F2