我需要使用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\"
我理解-Include
过滤器的工作方式一定有问题:
(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
我更喜欢通配符方法,因为没有多少人知道正则表达式。
答案 0 :(得分:2)
我不知道过滤器有什么问题,但你仍然可以做到
$files | % { copy-item ..\bin\release\$_ -Destination .\test}
如果你想保留直接结构,你必须稍微弱一点,比如:
$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
}
答案 1 :(得分:0)
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