如何使用powershell copy-item并保持结构

Syl*_*ain 42 powershell

我有一个如下所示的目录结构:

C:\folderA\folderB\folderC\client1\f1\files
C:\folderA\folderB\folderC\client1\f2\files
C:\folderA\folderB\folderC\client2\f1\files
C:\folderA\folderB\folderC\client2\f2\files
C:\folderA\folderB\folderC\client3\f1\files
C:\folderA\folderB\folderC\client4\f2\files
Run Code Online (Sandbox Code Playgroud)

我想复制c:\ tmp \中的f1文件夹的内容来获取它

C:\tmp\client1\f1\files
C:\tmp\client2\f1\files
C:\tmp\client3\f1\files
Run Code Online (Sandbox Code Playgroud)

我试过这个:

Copy-Item -recur -path: "*/f1/" -destination: C:\tmp\
Run Code Online (Sandbox Code Playgroud)

但它复制内容而不正确复制结构.

小智 44

在PowerShell 3.0及更高版本中,这可以通过以下方式完成:

Get-ChildItem -Path $sourceDir | Copy-Item -Destination $targetDir -Recurse -Container
Run Code Online (Sandbox Code Playgroud)

参考:Get-ChildItem

  • 请注意,在此示例中,`$ targetDir`必须已存在.在我的测试中,我发现当$ $ targetDir不存在时,文件将被复制,但目录结构将被展平. (11认同)
  • @Cullub关于`-container`标志,请参阅[Powershell的Copy-Item的-container参数的含义是什么?](/sf/ask/9036191/ -copy项容器-参数) (3认同)
  • bwerks 是正确的。不知道为什么这会收到任何选票。 (3认同)
  • 这是行不通的,我只是尝试过,结构就像 bwerks 评论中所说的那样被展平了 (3认同)
  • `-container`标志有什么作用? (2认同)

Joe*_*oey 13

使用xcopyrobocopy两者都是为此目的而设计的.当然,假设您的路径只是文件系统路径.

  • 我知道但我想在powershell中这样做,因为这是一个更大的脚本的一部分,我将把副本的输出(使用-PassThru)传递给其他命令. (4认同)

Sen*_*ent 12

电源外壳:

$sourceDir = 'c:\folderA\folderB\folderC\client1\f1'
$targetDir = ' c:\tmp\'

Get-ChildItem $sourceDir -filter "*" -recurse | `
    foreach{
        $targetFile = $targetDir + $_.FullName.SubString($sourceDir.Length);
        New-Item -ItemType File -Path $targetFile -Force;
        Copy-Item $_.FullName -destination $targetFile
    }
Run Code Online (Sandbox Code Playgroud)

注意:

  • -filter"*"没有做任何事情.它只是在这里说明您是否要复制某些特定文件.例如所有*.config文件.
  • 仍然必须使用-Force调用New-Item来实际创建文件夹结构.

  • FWIW,如果你在`$sourceDir` 上放置一个尾随目录分隔符,这将失败。 (2认同)

wor*_*yte 8

这里有另一个答案,但同样的解决方案虽然不是很清楚所以我会把它放进去,因为我花了一段时间才找到这个答案.

我一直在挖掘并找到了很多解决这个问题的方法,所有这些都是一些改动而不仅仅是一个直接的copy-item命令.在PS 3.0之前给出一些这些问题所以答案没有错,但是使用powershell 3.0我终于能够使用-Co​​ntainer开关来实现这一点.

Copy-Item $from $to -Recurse -Container
Run Code Online (Sandbox Code Playgroud)

这是我跑的测试,没有错误和目标文件夹代表相同的文件夹结构.

New-Item -ItemType dir -Name test_copy
New-Item -ItemType dir -Name test_copy\folder1
New-Item -ItemType file -Name test_copy\folder1\test.txt

# NOTE: with no \ at the end of the destination, the file
#       is created in the root of the destination, and
#       it does not create the folder1 container
#Copy-Item D:\tmp\test_copy\* D:\tmp\test_copy2 -Recurse -Container

# If the destination does not exist, this created the
# matching folder structure and file with no errors
Copy-Item D:\tmp\test_copy\* D:\tmp\test_copy2\ -Recurse -Container
Run Code Online (Sandbox Code Playgroud)

希望这有助于某人

  • 我尝试了这个,如果目标容器不存在,这只会传输没有文件夹的文件,这与 [Copy-Item](https://docs.microsoft.com/en-us/powershell/ 的文档所述相矛盾) module/microsoft.powershell.management/copy-item?view=powershell-5.1#example-3--将目录和内容复制到新目录)。我找到的唯一解决方案是在执行 Copy-Item cmdlet 之前创建目标文件夹。 (3认同)

Ada*_*ess 6

如果要使用 PowerShell 正确复制文件夹结构,请执行以下操作:

$sourceDir = 'C:\source_directory'
$targetDir = 'C:\target_directory'

Get-ChildItem $sourceDir -Recurse | % {
   $dest = $targetDir + $_.FullName.SubString($sourceDir.Length)

   If (!($dest.Contains('.')) -and !(Test-Path $dest))
   {
        mkdir $dest
   }

   Copy-Item $_.FullName -Destination $dest -Force
}
Run Code Online (Sandbox Code Playgroud)

这说明创建目录和复制文件。当然,如果您的文件夹包含句点,则您需要修改上面的 Contains() 调用,或者如果您想搜索您提到的“f1”,则需要添加过滤器。


Raf*_*sta 5

因为我花了时间寻找一种更直接的方法,不涉及管道或内联脚本:

Copy-Item -Path $sourceDir -Destination $destinationDir -Recurse -Container -Verbose
Run Code Online (Sandbox Code Playgroud)

-Filter如果需要复制的条件,也可以提供一个论据。

适用于 PowerShell 5.1.18362.752。

来源:https ://devblogs.microsoft.com/scripting/powertip-use-powershell-to-copy-items-and-retain-folder-struct/