web-dev-qa-db-ja.com

PowerShellを使用して、ファイルなしのフォルダー、フォルダーなしのファイル、またはすべてをコピーする

フォルダー(またはフォルダーのセット)を取得し、フォルダー構造(ファイルなし)を作成できる場所にファイル構造(フォルダーなし)を作成できるPowerShellスクリプトを作成できるようにしたいまたは、両方のファイル(すべてまたは選択したファイル)[〜#〜] and [〜#〜]フォルダーを作成できます。

    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など...

そして、フォルダー、ファイル、またはbothを含めるように選択的に選択します。

理想的な解決策は、(フォルダーの場合のみ)フォルダー構造を取得してエクスポート/保存し、それを読み取り、別の場所に同じ構造を作成することです。私が見つけたいくつかの解決策は、フォルダー構造のみをコピーしたと述べていますが、データが存在する場合、それもコピーされ、どちらか一方を除外することはできません。パスを半保持するというファイルのみの要件に対する部分的な解決策がありますが、ファイルが必要です。

c:\ProdData\Fld1\MyFile.dat

それを次の場所にコピーします。

c:\TestData\yyyyMMdd_hhmmss_ProdData_Fld1_MyFile.dat

しかし、これは簡単にデコードできるものではなく、ソース構造を再統合することは不可能です。ホイールを再発明せずにこれを達成する方法についての考えをいただければ幸いです。

20
steve_o

フォルダ階層内のすべてをコピーするには

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} 

幸運を!

19
Reinout

ここに、あなたが説明するそれぞれの状況を処理するためのいくつかのアイデアがあります。

フォルダ構造のみ

これにより、ソースが宛先にコピーされ、サブディレクトリが再帰的に実行されますが、すべてのファイルは除外されます。

robocopy $source $dest /e /xf *.*

ファイルのみ(フラットな構造)

これを処理する方法はいくつかありますが、特に良い方法やエレガントな方法は知りません。これは厄介ですが効果的なアプローチです。各サブディレクトリについて、ルートの宛先フォルダに再帰的でないコピーを実行します。批判やより良い代替案は大歓迎です。

Get-ChildItem $source -Recurse |
  Where-Object { $_.PSIsContainer -eq $true } |
  Foreach-Object { robocopy $_.FullName $dest }

すべて

このシナリオは、最も簡単なものです。

robocopy $source $dest /e

自分でスイッチを試して(途中でrobocopy /?を参照)、プロセスを微調整できます。私の意見で最もトリッキーなシナリオは、ディレクトリ構造を平坦化するシナリオです。複数のディレクトリにある同じファイル名をどのように処理するかなど、いくつかの決定が必要になります。

コマンドラインからオプションを受け入れる方法については、3つの状況に合わせてPowershellパラメーターセットをまとめることをお勧めします。コンセプトについて説明しているブログ投稿はたくさんありますが、TechNetを表示したり、Powershell内でhelp about_Functions_Advanced_Parametersを実行したりすることもできます。

30
ajk

以下は、ファイルなしで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 
1
Fred B

私は私の解決策を提案します:

$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
Esperento57