在PowerShell中递归地将一组文件从一个目录复制到另一个目录
Posted
技术标签:
【中文标题】在PowerShell中递归地将一组文件从一个目录复制到另一个目录【英文标题】:Recursively copy a set of files from one directory to another in PowerShell 【发布时间】:2014-11-07 03:34:41 【问题描述】:我正在尝试将所有*.csproj.user
文件从C:\Code\Trunk
递归复制到C:\Code\F2
。
例如:
C:\Code\Trunk\SomeProject\Blah\Blah.csproj.user
将被复制到:
C:\Code\F2\SomeProject\Blah\Blah.csproj.user
我目前的尝试是:
复制项目 C:\Code\Trunk -Filter *.csproj.user -Destination C:\Code\F2 -Recurse -WhatIf
但是我得到:
如果:对目标“项目”执行“复制目录”操作: C:\Code\Trunk 目的地:C:\Code\F2\Trunk"。
首先,它想将它们全部放在一个名为F2\Trunk
的新文件夹中,这是错误的。其次,它没有列出任何文件。应该有大约 10 个文件需要复制。
该命令的正确语法是什么?谢谢!
更新:
好吧,这似乎与C:\Code\F2
已经存在这一事实有关。如果我尝试将文件复制到不存在 的目的地,它会起作用。
我想覆盖目标中任何现有的.csproj.user
文件。
【问题讨论】:
关于创建新文件夹的部分是一个错误,已记录在here。 【参考方案1】:以前见过这个,我不知道为什么 PowerShell 似乎无法正确处理(恕我直言)。我会做的比较麻烦,但它确实有效。
$Source = 'C:\Code\Trunk'
$Files = '*.csproj.user'
$Dest = 'C:\Code\F2'
Get-ChildItem $Source -Filter $Files -Recurse | ForEach
$Path = ($_.DirectoryName + "\") -Replace [Regex]::Escape($Source), $Dest
If(!(Test-Path $Path))New-Item -ItemType Directory -Path $Path -Force | Out-Null
Copy-Item $_.FullName -Destination $Path -Force
【讨论】:
我认为如果您将参数-LiteralPath
用于Copy-Item
命令,您可以删除整个正则表达式
这似乎只从每个子文件夹中复制一个文件【参考方案2】:
答案 1 看起来不错,出于我的目的,我改为 Move-Item
。但是我发现在它递归遍历的每个文件夹中,它只移动了第一个文件。下面是我的完整脚本,其中还包括一些将 doc 文件转换为 pdf 的内容:
$Source = 'C:\Users\sgrody\Desktop\NSPM-Vol1'
$MoveFiles = '*.PDF'
$Dest = 'C:\Users\sgrody\Desktop\MedPassPDF'
$Folders = Get-ChildItem $Source -Directory -Recurse
ForEach ($Folder in $Folders)
$wdFormatPDF = 17
$word = New-Object -ComObject word.application
$word.visible = $false
$folderpath = "$($Folder.FullName)\*"
$fileTypes = "*.docx","*doc"
Get-ChildItem -path $folderpath -include $fileTypes |
foreach-object
$path = ($_.fullname).substring(0,($_.FullName).lastindexOf("."))
"Converting $path to pdf ..."
$doc = $word.documents.open($_.fullname)
$doc.saveas([ref] $path, [ref]$wdFormatPDF)
$doc.close()
$word.Quit()
Get-ChildItem $Source -Filter $MoveFiles -Recurse | ForEach
$Path = ($_.DirectoryName + "\") -Replace [Regex]::Escape($Source), $Dest
If(!(Test-Path $Path))New-Item -ItemType Directory -Path $Path -Force | Out-Null
Move-Item $_.FullName -Destination $Path -Force
【讨论】:
【参考方案3】:你们把这件事搞得极其复杂,其实很简单:
Copy-Item C:\Code\Trunk -Filter *.csproj.user -Destination C:\Code\F2 -Recurse
将复制目录,在 F2 中创建一个“Trunk”目录。如果您想避免创建*** Trunk 文件夹,您必须停止告诉 PowerShell 复制它:
Get-ChildItem C:\Code\Trunk | Copy-Item -Destination C:\Code\F2 -Recurse -filter *.csproj.user
【讨论】:
没有人会想到第一种方法是“告诉”它复制文件夹,因为“复制”是“复制项”的别名,而 DOS 中的“复制”没有如果我没记错的话,不是这样工作的。因此,许多人对此感到困惑和复杂。 对我来说,这会将所有内容展平并将所有内容复制到一个文件夹中 @Dan 不幸的是,Copy-Item 有一个,嗯,错误(已被禁止“破坏”旧脚本):如果要创建目标目录,可以使用第一个命令(只是复制项),如果它已经存在,那是你需要第二种语法的时候。 供将来参考:Rejected Edit 标题为“第一个表单无需复制根源文件夹即可工作,只需添加“*”,它只会复制其中的项目”建议更改最后一个Copy-Item C:\Code\Trunk\* -Filter *.csproj.user -Destination C:\Code\F2 -Recurse
的代码行:此编辑旨在解决帖子的作者,作为编辑没有任何意义。它应该写成评论或答案。
@yoyo 是的,我们使用 -filter 只是因为复制一个特定的扩展是原始请求...【参考方案4】:
虽然投票最多的答案对单一文件类型完全有效,但如果您需要复制多种文件类型,还有一个更有用的功能,称为 robocopy 正是为此目的,使用更简单
robocopy C:\Code\Trunk C:\Code\F2 *.cs *.xaml *.csproj *.appxmanifest /s
【讨论】:
我不得不使用 Robocopy,因为 Copy-Item 在较长的文件路径上出错【参考方案5】:我尝试了 Jaykul 的答案,但它对我不起作用。我必须按如下方式对其进行更改才能使其正常工作。我还在它工作之前创建了 C:\Code\F2 文件夹。
Get-ChildItem C:\Code\Trunk -Recurse -filter *.csproj.user | Copy -Destination C:\Code\F2
【讨论】:
正是我需要的。但必须在“递归”之前添加连字符【参考方案6】:最近我不得不替换几个子文件夹中存在的文件,我做了如下。
foreach($file in (Get-ChildItem File_you_want_to_be_copied.txt -Recurse)) $target=$file.directoryname; Copy-Item -path C:\Source_Path\File_you_want_to_be_copied.txt -Destination $target
【讨论】:
以上是关于在PowerShell中递归地将一组文件从一个目录复制到另一个目录的主要内容,如果未能解决你的问题,请参考以下文章
如何将一组 powershell 命令转换为可以在需要时运行的脚本?