【问题标题】:Powershell copy only selected files with folder structurePowershell仅复制具有文件夹结构的选定文件
【发布时间】:2019-11-15 09:40:40
【问题描述】:

我有一个包含很多文件的文件夹层次结构。 我需要复制所有文件夹,并且只复制选定的文件。为此,我编写了脚本:

$path = "D:\Drop\SOA-ConfigurationManagement - Test\181"
$files = Get-ChildItem -Path $path -Recurse | ? { $_.Name -like "system.serviceModel.client.config" }
$Destination = "D:\test\"
Copy-Item $files -Destination $Destination -recurse

当我执行变量 $files 时,它返回正确的路径:

但是当我执行 Copy-Item 时,它返回的不是完整路径:

也许我的方法是错误的。如果是这样,如何复制整个文件夹结构,并且只复制选定的文件(在这种情况下是 system.serviceModel.client.config 文件)?

UPD1 好的,我找到了,如何只复制文件夹:

$path = "D:\Drop\SOA-ConfigurationManagement - Test\181\"
$Destination = "D:\test\"
Copy-Item $path $Destination -Filter {PSIsContainer} -Recurse -Force

但是如何只复制选定的文件,保留它们的位置? $Destination 变量中需要包含什么?

$files = Get-ChildItem -Path $path -Recurse | ? { $_.Name -like "system.serviceModel.client.config" } | % { Copy-Item -Path $_.FullName -Destination $Destination }

【问题讨论】:

    标签: powershell copy-item


    【解决方案1】:

    这段代码也会保持目录结构不变

    $path = "D:\Drop\SOA-ConfigurationManagement - Test\181\"
    $Destination = "D:\test\"
    $fileName = "system.serviceModel.client.config"
    Get-ChildItem -Path $path -Recurse |  ForEach-Object {
        if($_.Name -like $fileName) {
            $dest = "$Destination$(($_.FullName).Replace($path,''))"
            $null = New-Item $dest -Force
            Copy-Item -Path $_.FullName -Destination $dest -Force
        }
    }
    

    【讨论】:

    • 不幸的是,第一个变体根本没有复制任何文件,第二个 - 只有一个文件 system.serviceModel.client.config 的副本被复制到 D:\test 的根目录中,没有任何文件夹结构
    • @VasiliyVegas 根据您的 cmets 我编辑了我的答案。希望它现在可以工作。
    【解决方案2】:

    要复制整个文件夹结构和具有特定名称的文件,下面的代码应该做你想做的:

    $Source      = 'D:\Drop\SOA-ConfigurationManagement - Test\181'
    $Destination = 'D:\test'
    $FileToCopy  = 'system.serviceModel.client.config'
    
    # loop through the source folder recursively and return both files and folders
    Get-ChildItem -Path $Source -Recurse | ForEach-Object {
        if ($_.PSIsContainer) {
            # if it's a folder, create the new path from the FullName property
            $targetFolder = Join-Path -Path $Destination -ChildPath $_.FullName.Substring($Source.Length)
            $copyFile = $false
        }
        else {
            # if it's a file, create the new path from the DirectoryName property
            $targetFolder = Join-Path -Path $Destination -ChildPath $_.DirectoryName.Substring($Source.Length)
            # should we copy this file? ($true or $false)
            $copyFile = ($_.Name -like "*$FileToCopy*")
        }
        # create the target folder if this does not exist
        if (!(Test-Path -Path $targetFolder -PathType Container)) {
            $null = New-Item -Path $targetFolder -ItemType Directory
        }
        if ($copyFile) {
            $_ | Copy-Item -Destination $targetFolder -Force
        }
    }
    

    【讨论】:

      【解决方案3】:

      试试这个

      $path = 'D:\Drop\SOA-ConfigurationManagement - Test\181\'
      $Destination = 'D:\test\'
      
      $files = Get-ChildItem -Path $path -Recurse -File | where Name -like "*system.serviceModel.client.config*" | %{
      
      $Dir=$_.DirectoryName.Replace($path, $Destination)
      $NewPAthFile=$_.FullName.Replace($path, $Destination)
      
      #create dir if not exists
      New-Item -Path $Dir -ItemType Directory -Force -ErrorAction SilentlyContinue
      
      #copy file in new dir
      Copy-Item $_.FullName $NewPAthFile 
      
      
      }
      

      【讨论】:

        【解决方案4】:

        我建议做以下改动:

        $path = "D:\Drop\SOA-ConfigurationManagement - Test\181"
        $files = Get-ChildItem -Path $path -Recurse | ? { $_.Name -like "system.serviceModel.client.config" }
        $Destination = "D:\test\"
        $files | % { $_ | Copy-Item -Destination $Destination -recurse }
        

        您甚至可以将整个副本放在一行中:

        $path = "D:\Drop\SOA-ConfigurationManagement - Test\181"
        $Destination = "D:\test\"
        Get-ChildItem -Path $path -Recurse | ? { $_.Name -like "system.serviceModel.client.config" } | % { $_ | Copy-Item -Destination $Destination -recurse }
        

        Copy-Item 可以从输入对象流中找到路径,但它似乎无法将System.IO.FileInfo 对象的集合作为Path 的参数。

        【讨论】:

          猜你喜欢
          • 2017-11-24
          • 2019-09-07
          • 1970-01-01
          • 1970-01-01
          • 2013-02-27
          • 1970-01-01
          • 2011-08-24
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多