使用 PowerShell 复制没有文件的文件夹、没有文件夹的文件或所有内容

Posted

技术标签:

【中文标题】使用 PowerShell 复制没有文件的文件夹、没有文件夹的文件或所有内容【英文标题】:Copy folders without files, files without folders, or everything using PowerShell 【发布时间】:2012-04-17 07:21:58 【问题描述】:

我希望能够编写一个 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 脚本,可以在别处复制该文件夹结构,让我可以选择仅文件夹结构仅文件文件AND 文件夹 被复制。

在上面,我希望能够将 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

但这不是可以轻易解码的东西,也不可能重新整合源结构。对于如何在不重新发明***的情况下实现这一点的任何想法,我将不胜感激。

【问题讨论】:

【参考方案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 或在 Powershell 中运行 help about_Functions_Advanced_Parameters

【讨论】:

感谢您的建议。我什至没有安装 Robocopy,它非常适合需求。我最终对文件结构所做的是将 Show-Tree 通过管道传输到文本文件。这完成了我所追求的另一部分。没有一件事能做到这一切,但是 3 个相对简单的部分一起完成了我所需要的。感谢您的帮助! 对于扁平化的,您可以跳过中间部分,只需在 Get-ChildItem 上使用 -File 选项(和 Copy-Item 而不是 robocopy): Get-ChildItem $source -Recurse -File | Foreach 对象 复制项 $_.FullName $dest 。不过差别不大。 @Brandon 好点。只要您使用的是 Powershell 3,您当然可以这样做(-File-Directory 参数直到 v3 才存在)。【参考方案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 

祝你好运!

【讨论】:

我发现这对于过滤掉特定文件以进行复制非常有帮助。所需要的只是在 foreach $filename = $_.Name 中添加一个变量,并带有一个 if 检查 if ($filename.endswith("dll"),我可以为开发环境调试会话提取 dll。请注意,您可能希望过滤掉系统 dll :)。【参考方案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 

【讨论】:

【参考方案4】:

我提出我的解决方案:

$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

【讨论】:

只为复制文件投票。我无法与其他示例一起使用。

以上是关于使用 PowerShell 复制没有文件的文件夹、没有文件夹的文件或所有内容的主要内容,如果未能解决你的问题,请参考以下文章

powershell Quick Powershell脚本用于复制文件并使用文件类型过滤保留文件夹结构

powershell Quick Powershell脚本用于复制文件并使用文件类型过滤保留文件夹结构

使用 PowerShell 将列从一个 csv 文件复制到另一个

如何使用PowerShell将选择查询的输出从DataSet复制到日志文件?

powershell 使用 Copy_Item cmdlet 将文件复制到远程计算机问题

如何在 PowerShell 中使用 tar 和 tee 进行一次读取、多次写入、原始文件副本