【问题标题】:Powershell Copy Directories - Using A CSV Listing - Source - Destination PathPowershell 复制目录 - 使用 CSV 列表 - 源 - 目标路径
【发布时间】:2016-06-28 04:44:15
【问题描述】:

我正在尝试使用列出要复制的每个目录或文件夹的源和目标的 CSV 文件复制目录 - 文件夹和子文件夹到另一个位置。

CSV 的内容如下:

我已经引用了这个帖子:

https://serverfault.com/questions/399325/copying-list-of-files-through-powershell

 Import-CSV C:\Users\WP\Desktop\a.csv | foreach{Copy-item "$_.Source" "$_.Destination"}

收到错误

CategoryInfo          : ObjectNotFound: (@{Source=C:String) [Copy-Item], DriveNotFoundException
+ FullyQualifiedErrorId : DriveNotFound,Microsoft.PowerShell.Commands.CopyItemCommand

我的另一个问题是,如果我想在 CSV 中复制到一个目标中不存在的文件夹 - 我可以使用 CSV 命令 powershell 创建文件夹吗? p>

感谢您的建议。

【问题讨论】:

    标签: csv powershell copy directory


    【解决方案1】:

    如果默认情况下将它们放在双引号中,PowerShell 将不会扩展变量并访问变量内对象的属性。只有 '$_' 被扩展并且 '.source' 被附加到字符串的末尾,所以从 shell 的角度来看,你的命令看起来像 Copy-item "{source=C:\Users\WP\Desktop\a;Destination=C:\Users\WP\Desktop\a}.Source" "{source=C:\Users\WP\Desktop\a;Destination=C:\Users\WP\Desktop\a}.Destination",这可能不是你的意思。

    这是应该起作用的语法(我还包括了-Recurse,以便它也会复制目录中的项目)

    Import-CSV C:\Users\WP\Desktop\a.csv | foreach{Copy-item  -Path $_.Source -Destination $_.Destination -Recurse}
    

    注意:如果要访问双引号内对象的属性,请使用此语法"$($_.source)"

    【讨论】:

    • 谢谢你们-约翰的回答也在目的地创建了文件夹。
    【解决方案2】:

    对于这样的 csv:

    Source,Destination
    D:\junk\test1,D:\junk\test3 
    D:\junk\test2,D:\junk\test4 
    

    您可以使用如下代码:

    $csv = Import-Csv D:\junk\test.csv 
    $csv | ForEach-Object {
        if (-not (Test-Path $_.Destination)) {
            New-Item -Name $_.Destination -ItemType Directory -Force -WhatIf
        }
        Copy-Item $_.Source $_.Destination -Recurse -Force -WhatIf
    }
    

    更多关于 PowerShell 的学习建议:

    1. 使用WhatIf 进行测试。

    2. 研究这段代码每一行的作用。

    3. 用代码试验看看它的作用。

    4. 了解并使用调试器 (PowerShell ISE) 来帮助您编写更好的代码。

    5. 从代码中删除WhatIf参数,让它真正执行...

    【讨论】:

    • 谢谢 - 它似乎工作:) - 我会花一些时间调查。我感谢所有的帮助。以防万一文件夹不存在 - 这会在目的地创建文件夹吗?
    • AFAIK,-Recurse 参数会导致在必要时创建目标文件夹。
    • 是的,我为“教学”方面添加了更多测试路径和新项目调用。并非所有可以写在一行中的代码都应该是,并且取决于用户接下来打算做什么可能会使事情变得更容易(可能是复制文件,可能是日志操作等)。
    【解决方案3】:

    如果您有几十个问题都涉及对列表的每个元素执行相同的操作,您可能需要考虑获取或编写通用 CSV 模板扩展工具,例如 Expand-csv。使用此工具,您可以从 CSV 文件和模板开始,然后生成包含所有命令的脚本。

    Sample.csv 如下所示:

    Source,Destination
    C:\Users\WP\Desktop\a,C:\Users\WP\Desktop\c
    C:\Users\WP\Desktop\b,C:\Users\WP\Desktop\d
    

    Sample.tmplt 看起来像这样:

    Copy-Item -Path $Source -Destination $Destination -Recurse
    

    调用 Expand-csv 的命令如下所示:

    Expand-csv Sample.csv Sample.tmplt > Sample.ps1
    

    输出文件 Sample.ps1 为 CSV 文件中的每个条目包含一个复制命令

    这里是Expand-csv的定义:

    <#  This function is a table driven template tool. 
        It's a refinement of an earlier attempt.
    
        It generates output from a template and
        a driver table.  The template file contains plain
        text and embedded variables.  The driver table 
        (in a csv file) has one column for each variable, 
        and one row for each expansion to be generated.
    
        5/13/2015
    
    #>
    
    function Expand-csv {
       [CmdletBinding()]
       Param(
          [Parameter(Mandatory=$true)]
          [string] $driver,
          [Parameter(Mandatory=$true)]
          [string] $template
       )
       Process
       {
          $OFS = "`r`n"
          $list = Import-Csv $driver
          [string]$pattern = Get-Content $template
    
          foreach ($item in $list) {
             foreach ($key in $item.psobject.properties) {
                Set-variable -name $key.name -value $key.value
                }
             $ExecutionContext.InvokeCommand.ExpandString($pattern) 
             }
       }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-25
      • 1970-01-01
      • 1970-01-01
      • 2019-06-08
      • 2011-04-24
      相关资源
      最近更新 更多