在 Windows Powershell 中复制文件夹时出现意外结构 [英] unexpected structure when copying folders in Windows Powershell
问题描述
我有一组项目,其中包含项目特定文件和通用文件的混合.我正在尝试将两个不同文件夹(一个项目特定文件夹和一个公共文件夹)中的内容复制到一个以项目命名的文件夹中.我还想保留原始文件夹中的所有文件夹层次结构.
I have a set of projects that involve a mix of project-specific files plus common files. I'm trying to copy contents from two different folders -- a project-specific folder, and a common folder -- into a single folder named for the project. I also want to retain any folder hierarchies from the original folders.
比如一些常用文件的路径:
For example, some paths to the common files:
src\Common\PackageAssets\logo1.jpg
src\Common\PackageAssets\logo2.jpg
以及项目特定文件的示例路径:
And example paths to project-specific files:
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
但不是预期的结果,所有文件都在一个额外级别的子文件夹中结束:
But instead of the expected results, all the files are ending up in an extra level of subfolder:
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,但随后子文件夹层次结构丢失了.
I'm stumped. I can't figure out how to get rid of the extra subfolder layer. I tried using Get-ChildItem piping to Copy-Item, but then the subfolder hierarchies were lost.
在 .bat 文件中,这是有效的:
In a .bat file, this works:
xcopy src\Common\PackageAssets\* bld\%project\pkg_contents /s
xcopy src\Projects\%project\PackageFiles bld\%project\pkg_contents /s
我想我可以使用 xcopy,但肯定有一种方法可以使用 cmdlet 来做到这一点.
I guess I could use xcopy, but surely there must be a way to do this using cmdlets.
推荐答案
您描述的行为是 已知问题:
The behavior you describe is a known problem as of Windows PowerShell v5.1 / PowerShell Core v6.2.0-preview.2, unfortunately:
简而言之,Copy-Item
的行为遗憾地取决于目标目录是否已经存在:
如果是目标目录.存在,复制的不是源目录的内容,而是源目录.作为一个整体,到以源目录命名的目标目录的子目录.
If the target dir. exists, it is not the source directory's content that is copied, but the source dir. as a whole, to a subdirectory of the target directory named for the source dir.
解决方法 已在 PetSerAl 对该问题的有用评论中详细说明:
The workaround is already mostly spelled out in PetSerAl's helpful comment on the question:
复制之前,请确保目标目录存在.
Before copying, make sure that the target directory exists.
将 \*
附加到源路径以明确定位源目录的内容.
Append \*
to the source path to explicitly target the contents of the source dir.
- 同时指定
-Force
,以确保隐藏的文件和目录也被复制.
- Also specify
-Force
, so as to ensure that hidden files and directories are also copied.
$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
可能失败 有时,您无法预测何时会发生这种情况 - 请参阅此答案以获得可靠的替代方案.
A note re use of Remove-Item -Recurse
to clear out preexisting destination-directory content, if needed: Regrettably, Remove-Item
can fail on occasion and you cannot predict when that happens - see this answer for a robust alternative.
这篇关于在 Windows Powershell 中复制文件夹时出现意外结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!