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

3
我是一名有用的助手,可以为您翻译文本。
我有一组项目,涉及特定于项目的文件和公共文件的混合。我试图将来自两个不同文件夹(一个特定于项目的文件夹和一个公共文件夹)的内容复制到以项目命名的单个文件夹中。我还希望保留原始文件夹中的任何文件夹层次结构。
例如,某些通用文件的路径:
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\pkgFiles"

# 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,但肯定有一种使用cmdlets来完成这个任务的方法。


1
New-Item bld\ProjectA\pkgFiles -Type Directory; Copy-Item -Path .\src\Common\PackageFile\* bld\ProjectA\pkgFiles -Recurse; Copy-Item -Path .\src\Projects\ProjectA\PackageFiles\* bld\ProjectA\pkgFiles -Recurse - user4003407
另一个奇怪的事情是,当我在控制台中运行命令和从脚本中运行命令时,结果是不同的。 - Peter Constable
1个回答

2
您描述的行为是Windows PowerShell v5.1 / PowerShell Core v6.2.0-preview.2已知的问题,不幸的是:
简而言之,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以获取一个强大的替代方案。

1
在我的情况下,我已经创建了目标文件夹,但仍然遇到问题。然而,我没有添加 *,这就是区别所在。 - Peter Constable

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接