【问题标题】:XCOPY deployment script - how to include certain files?XCOPY 部署脚本 - 如何包含某些文件?
【发布时间】:2013-02-04 16:33:56
【问题描述】:

我只需要使用 Powershell 复制文件夹的某些部分,特别是这个列表:

$files = @("MyProgram.exe",
           "MyProgram.exe.config",
           "MyProgram.pdb",
           ".\XmlConfig\*.xml")

以人类可读的形式:目标文件夹根目录下的 3 个特定 MyProgram.* 文件和 XmlConfig 文件夹下的所有 XML 文件,该文件夹本身位于源路径的根目录下(在我的情况下为 ..\bin\Release\)。 XmlConfig 文件夹必须在目的地创建,如果它不存在。

我尝试过的:

(1) 我尝试了以下方法,但没有成功,即在目标路径没有创建文件夹或文件:

Copy-Item -Recurse -Path "..\bin\Release\" -Destination ".\Test\" -Include $files

(2) 当-Include被删除时,整个文件夹结构创建成功,包括子文件夹和文件:

Copy-Item -Recurse -Path "..\bin\Release\" -Destination ".\Test\"

我对@9​​87654329@过滤器工作原理的理解一定有问题:

(3) 我测试了-Include 需要一个通配符数组的假设,但这也不起作用:

$files = @("*MyProgram.exe*",
           "*MyProgram.exe.config*",
           "*MyProgram.pdb*",
           "*.\XmlConfig\*.xml*")

请就我的情况如何正确处理Copy-Item提出建议。

更新(基于以下答案):

我正在寻找一个接受字符串数组的通用实现。它打开了将所有必要的文件/路径放在一个地方的可能性,以便于编辑,以便非 Powershell 知识的人可以根据需要理解和修改它。因此,最终它将是为任何项目执行 XCOPY 部署的单个脚本,输入文件是唯一的可变部分。对于上面的例子,输入看起来像这样(保存为input.txt 并作为参数传递给主脚本):

MyProgram.exe
MyProgram.exe.config
MyProgram.pdb
.\XmlConfig\*.xml

我更喜欢通配符方法,因为知道正则表达式的人并不多。

【问题讨论】:

    标签: powershell xcopy


    【解决方案1】:

    我不知道过滤器有什么问题,但你仍然可以这样做

    $files | % { copy-item ..\bin\release\$_ -Destination .\test}
    

    如果你想保留directoty 结构,你必须弱化一点,比如:

    $sourcedir="c:\temp\test"
    $f=@("existing.txt","hf.csv";"..\dir2\*.txt")
    $f |%{
         $source=ls (join-Path $sourcedir $_) |select -expand directoryname    
         if ("$source" -like "$sourcedir*"){
            $destination=$source.Substring($sourcedir.Length)+".\" 
         }
         else{
            $destination=$_
         }  
        copy-item $sourcedir\$_ -Destination $destination -WhatIf
    }
    

    【讨论】:

    • -过滤器只接受一个字符串
    • 我需要在目标文件夹中才能正常工作。但如果我在目标文件夹中,..\bin\release 将不起作用。或者$files需要指定我不想要的绝对路径。
    • 这就是您在示例中所做的...相对路径和通配符也适用于我的代码
    • 如果我让您的代码保持原样,它会创建一个文件夹大小的文件,因此似乎所有内容都附加到一个文件中。如果我添加尾部反斜杠 .\test\ ,它会在每个被复制的文件中显示此错误:Copy-Item : The filename, directory name, or volume label syntax is incorrect. 我试图将相关部分用双引号引起来 - 结果相同。
    • 不知何故,我几乎让它作为生产脚本的一部分工作,即使它在测试中不合作。唯一的问题是它不保留文件夹结构,因此所有文件最终都在同一个文件夹中,包括来自.\XmlConfig\ 的文件。我试过-Container标志,它应该保留文件夹结构,但它没有效果。
    【解决方案2】:

    AFAICT -Include 仅适用于文件名或目录名,而不适用于组合,即路径。你可以试试这样的:

    $files = 'MyProgram\.exe|MyProgram\.exe\.config|MyProgram\.pdb|XmlConfig\\.*?\.xml'
    
    Get-ChildItem ..\bin\release -r | Where {!$_.PSIsContainer -and ($_.FullName -match $files)} | 
        Copy-Item -Dest .\test
    

    使用通配符,您可以这样做:

    $files = @('*MyProgram.exe','*MyProgram.exe.config','*MyProgram.pdb','*\XmkConfig\*.xml')
    Get-ChildItem ..\bin\release -r |
        Foreach {$fn=$_.Fullname;$_} | 
        Where {!$_.PSIsContainer -and ($files | Where {$fn -like $_})} | 
        Copy-Item -Dest .\test    
    

    【讨论】:

    • 有没有办法让通用实现接受一个字符串数组?我最初想将所有必要的文件/路径放入一个here字符串(可以用换行符分割,以适应这个字符串数组概念),甚至是一个单独的文件,以便于编辑,这样一个非Powershell知识渊博的人可以根据需要理解和修改。
    • 当然,这很容易。另一个问题是您是否想坚持使用正则表达式模式或更有限的通配符模式?如果您对正则表达式没问题,则将每个模式放在文件中的一行上,然后像这样重构 $files:$OFS="|"; $files = "$(get-content files.txt)"。注意:该特定方法不允许文件中的任何位置出现空行。
    • 我更喜欢通配符,没有多少人知道正则表达式。此外,预计表达式不会如此复杂以至于需要正则表达式。我可以确保输入文件遵循一些特定的格式,只要它易于维护。你能举个通配符的例子吗?
    • @KeithHill 你的意思是 $EOF 吗?
    • 使用通配符,您需要修改匹配逻辑。我很快就会在这里更新答案。 @Kayasax,不,我的意思是 $OFS(输出字段分隔符)。
    猜你喜欢
    • 2015-10-02
    • 2021-02-01
    • 2013-07-02
    • 1970-01-01
    • 2012-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-17
    相关资源
    最近更新 更多