Скопируйте папки без файлов, файлов без папок или всего, используя PowerShell
Я хотел бы иметь возможность написать PowerShell script, который возьмет папку (или набор папок) и дублирует их, в которой может быть создана структура папок (без файлов), где файловая структура ( без папок) или в которых могут быть созданы как файлы (все или выбранные) И.
Example:
C:\ProdData has 3 subfolders in it
C:\ProdData\Fld1
C:\ProdData\Fld2
C:\ProdData\Fld3 - has 2 subfolders under it
C:\ProdData\Fld3\MyFolder1
C:\ProdData\Fld3\MyFolder2
Каждая папка выше содержит в себе различное количество файлов различного размера, различных расширений файлов.
Я хотел бы иметь PowerShell script, который бы дублировал эту структуру папок в другом месте, предоставляя мне выбор Только структура папки, Только файлы или Файлы и папки, которые нужно скопировать.
В приведенном выше, я хотел бы иметь возможность скопировать C:\ProdData в другую папку, по существу переименовав ProdData в TestData (то есть C:\ProdDatastrong > , скопированный в C:\TestDatastrong > ) или скопировать всю структуру папок.
C:\ProdData
в другую папку, которая является подпапкой чего-то еще: C:\TestArea\TestFolders\2012-04-01\TestData\ProdData\Fld1
и т.д.
И выборочно выберите папки, файлы или и то, и другое.
Идеальное решение будет состоять в том, чтобы (только для папок) использовать структуру папок, экспортировать/сохранить его, прочитать в ней и создать ту же структуру в другом месте. Некоторые решения, которые я нашел, говорят, что они скопировали структуру папок только, но если данные существуют, они также копируются, и вы не можете исключить тот или иной. У меня есть частичное решение для требования только к файлам, которое полу-сохраняет путь, но для этого потребуется файл:
c:\ProdData\Fld1\MyFile.dat
и скопируйте его на:
c:\TestData\yyyyMMdd_hhmmss_ProdData_Fld1_MyFile.dat
Но это не то, что может быть легко декодировано и невозможно было бы повторно интегрировать исходную структуру. Я был бы признателен за любые мысли о том, как это сделать, не изобретая колесо.
Ответы
Ответ 1
Вот некоторые идеи для обработки каждой описываемой ситуации.
Только структура папки
Это скопирует источник в пункт назначения, рекурсивный подкаталоги, но исключая все файлы.
robocopy $source $dest /e /xf *.*
Только файлы (структура сглаживания)
Есть несколько способов справиться с этим, но я не знаю особо хорошего или элегантного способа. Здесь неудобный, но эффективный подход - для каждого подкаталога он запускает нерекурсивную копию в корневую папку назначения. Критика или более приятные альтернативы были бы наиболее желанными.
Get-ChildItem $source -Recurse |
Where-Object { $_.PSIsContainer -eq $true } |
Foreach-Object { robocopy $_.FullName $dest }
Все
Этот сценарий является наиболее простым из этой группы.
robocopy $source $dest /e
Вы можете поэкспериментировать с самими переключателями (ссылаясь на robocopy /?
на этом пути), чтобы точно настроить процесс. Самый сложный сценарий, на мой взгляд, тот, который выравнивает структуру каталогов. У вас возникнут некоторые решения, например, как вы хотите обрабатывать одно и то же имя файла, отображаемое в нескольких каталогах.
Что касается того, как принимать параметры из командной строки, я бы предложил собрать набор параметров Powershell для ваших трех ситуаций. Есть несколько сообщений в блоге, в которых обсуждается концепция, но вы также можете увидеть TechNet или запустить help about_Functions_Advanced_Parameters
внутри Powershell.
Ответ 2
Чтобы скопировать все в иерархию папок
Copy-Item $source $dest -Recurse -Force
Чтобы скопировать иерархию, вы можете попробовать:
$source = "C:\ProdData"
$dest = "C:\TestData"
Copy-Item $source $dest -Filter {PSIsContainer} -Recurse -Force
Чтобы сгладить файловую структуру, вы можете попробовать:
$source = "C:\ProdData"
$dest = "C:\TestData"
New-Item $dest -type directory
Get-ChildItem $source -Recurse | `
Where-Object { $_.PSIsContainer -eq $False } | `
ForEach-Object {Copy-Item -Path $_.Fullname -Destination $dest -Force}
Удачи!
Ответ 3
Следующие копии только структуры папок формы ProdData для TestData без каких-либо файлов
$from = "C:\ProdData"
$to = "C:\TestData"
Get-ChildItem -Path $from -Recurse |
?{ $_.PSIsContainer } |
Copy-Item -Destination {Join-Path $to $_.Parent.FullName.Substring($from.length)} -Force