Копировать папки без файлов, файлы без папок или все, используя PowerShell - PullRequest
19 голосов
/ 03 апреля 2012

Я хотел бы иметь возможность написать сценарий PowerShell, который будет принимать папку (или набор папок) и дублировать их, в которых можно создать структуру папок (без файлов), где будет структура файлов (без папки) или в которых могут быть созданы оба файла (все или выбранные) И папки.

    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, который дублировал бы эту структуру папок в другом месте, предоставляя мне выбор Только структура папок , Только файлы или Файлы И папки для копирования.

Выше я хотел бы иметь возможность скопировать C: \ ProdData в другую папку, по сути переименовав ProdData в TestData (то есть C: \ ProdData , скопированный в C: \ TestData ), или скопировать всю структуру папок.

C:\ProdData в другую папку, которая является подпапкой чего-то другого: C:\TestArea\TestFolders\2012-04-01\TestData\ProdData\Fld1 и т. Д. *

И выборочно включить папки, файлы или оба .

Идеальным решением было бы (только для папок) взять структуру папок, экспортировать / сохранить ее, прочитать ее и создать такую ​​же структуру в другом месте. В некоторых решениях, которые я нашел, сказано, что они копируют только структуру папок, но если данные существуют, они тоже копируются, и вы не можете исключить одно или другое. У меня есть частичное решение требования, касающегося только файлов, которое частично сохраняет путь, но для этого потребуется файл:

c:\ProdData\Fld1\MyFile.dat

и скопируйте его в:

c:\TestData\yyyyMMdd_hhmmss_ProdData_Fld1_MyFile.dat

Но это не то, что можно легко декодировать, и было бы невозможно реинтегрировать структуру источника. Буду признателен за любые мысли о том, как сделать это, не изобретая колесо.

Ответы [ 4 ]

30 голосов
/ 03 апреля 2012

Вот несколько идей для обработки каждой ситуации, которую вы описываете.

Только структура папки

Это скопирует источник в место назначения, рекурсивные подкаталоги, но исключая все файлы.

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.

19 голосов
/ 09 декабря 2014

Чтобы скопировать все в иерархии папок

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} 

Удачи!

1 голос
/ 13 июня 2018

Я предлагаю свое решение:

$source = "C:\temp\"
$dest = "C:\TestData\"

#create destination directory if dont exist
New-Item -ItemType Directory $dest -Force


#To copy everything in a folder hierarchie
Get-ChildItem $source -Recurse | Copy-Item -Destination {$_.FullName.Replace($source, $dest)}  -Force

#To copy only directory hierarchie:
Get-ChildItem $source -Recurse -directory | Copy-Item -Destination {$_.FullName.Replace($source, $dest)}  -Force

#To copy only file (remove doublon be carefull):
Get-ChildItem $source -Recurse -file | Copy-Item -Destination $dest -Force
1 голос
/ 11 января 2018

Следующие копии копируют только структуру папок из 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 
...