【问题标题】:Recursively copy a set of files from one directory to another in PowerShell在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

标签: windows powershell powershell-2.0


【解决方案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} 
    

    【讨论】:

      猜你喜欢
      • 2012-02-15
      • 1970-01-01
      • 2013-06-01
      • 2020-06-22
      • 2014-08-12
      • 2013-10-24
      • 2011-10-24
      • 1970-01-01
      相关资源
      最近更新 更多