在Windows Powershell中复制文件夹时出现意外结构

时间:2017-12-24 22:32:02

标签: windows powershell

我有一组涉及项目特定文件和常用文件的项目。我试图将内容从两个不同的文件夹(项目特定文件夹和公共文件夹)复制到为项目命名的单个文件夹中。我还想保留原始文件夹中的任何文件夹层次结构。

例如,公共文件的一些路径:

src\Common\PackageAssets\logo1.jpg
src\Common\PackageAssets\logo2.jpg

项目特定文件的示例路径:

src\Projects\ProjectA\PackageFiles\readme.txt
src\Projects\ProjectA\PackageFiles\scale-100\projA.png

复制后的所需结果为:

bld\ProjectA\pkgFiles\logo1.png
bld\ProjectA\pkgFiles\logo2.png
bld\ProjectA\pkgFiles\readme.txt
bld\ProjectA\pkgFiles\scale-100\projA.png

我使用的是:

[string]$pkgContentPath = "bld\$project\pkg_contents"

# copy common files
Copy-Item -Path .\src\Common\PackageAssets -Recurse -Destination $pkgContentPath
# copy project-specific files
Copy-Item -Path .\src\Projects\ProjectA\PackageFiles\ -Recurse -Destination $pkgContentPath

但是,不是预期的结果,所有文件都以一个额外的子文件夹级别结束:

bld\ProjectA\pkgFiles\PackageAssets\logo1.png
bld\ProjectA\pkgFiles\PackageAssets\logo2.png
bld\ProjectA\pkgFiles\PackageFiles\readme.txt
bld\ProjectA\pkgFiles\PackageFiles\scale-100\projA.png

我很难过。我无法弄清楚如何摆脱额外的子文件夹层。我尝试将Get-ChildItem管道用于Copy-Item,但子文件夹层次结构丢失了。

在.bat文件中,这有效:

xcopy src\Common\PackageAssets\* bld\%project\pkg_contents /s
xcopy src\Projects\%project\PackageFiles bld\%project\pkg_contents /s

我想我可以使用xcopy,但肯定必须有一种方法可以使用cmdlet来实现这一点。

1 个答案:

答案 0 :(得分:0)

从Windows PowerShell v5.1 / PowerShell Core v6.2.0-preview.2开始,您描述的行为是 known problem ,不幸的是:

简而言之,Copy-Item行为令人遗憾地取决于目标目录是否已经存在

如果是目标目录。存在,它不是复制的源目录的内容,而是源目录。 作为一个整体,指向为源目录命名的目标目录的子目录

解决方法已经在PetSerAl对该问题的有用评论中大致阐述:

  • 复制前,请确保目标目录存在。

  • \*附加到源路径,以明确定位源目录的内容

    • 同时指定-Force,以确保同时复制隐藏文件和目录。
$pkgContentPath = "bld\$project\pkg_contents"

# Make sure the target dir. exists.
# (-Force leaves an existing dir alone and otherwise creates it.)
New-Item -Force -Type Directory $pkgContentPath

# IF desired, clear out the pre-existing directory content.
# !! Beware of Remove-Item's intermittent failures - see below.
#  Remove-Item -Force $pkgContentPath\* -Recurse.

# Copy with \* appended to the source paths and -Force added:
#
# copy common files
Copy-Item -Recurse -Force -Path .\src\Common\PackageAssets\* $pkgContentPath
# copy project-specific files
Copy-Item -Recurse -Force -Path .\src\Projects\ProjectA\PackageFiles\* $pkgContentPath

如果需要,请重新使用Remove-Item -Recurse清除预先存在的目标目录内容:遗憾的是,Remove-Item有时会失败而您无法预测何时发生 - 请参阅this answer了解强有力的替代方案。