英文:
How To: Move Files Preserving Directory Structure and Rename Existing Files? (Script Debug)
问题
尝试调试文件传输操作。基本上,我想要使用 PowerShell 合并两个文件夹($sourceDir 和 $targetDir),并重命名在 $sourceDir 中已经存在于 $targetDir 中的任何文件。它在某种程度上完成了这个任务,但与保留源文件夹的目录结构不同,它将所有文件从源目录移动到目标目录的根目录。
我知道在标准 Move-Item 命令上添加 -Container 标志将强制它重新构建目录结构,但我在这里尝试添加它时会出现错误。
这是我的代码:
$sourceDir = "E:\Folder1"
$targetDir = "W:\Folder1"
Get-ChildItem -Path $sourceDir -Recurse | ForEach-Object {
$num=1
$nextName = Join-Path -Path $targetDir -ChildPath $_.name
while(Test-Path -Path $nextName)
{
$nextName = Join-Path $targetDir ($_.BaseName + "_$num" + $_.Extension)
$num+=1
}
$_ | Move-Item -Destination $nextName -Verbose
}
我在 Move-Item 命令的上方插入了 write-host 行,我可以确认它的目标是目标目录的根目录,而不是保持源的目录结构。我尝试将 Get-ChildItem -Path
更改为 -LiteralPath
,我尝试在 GCI 之后添加 | % { $_.FullName } |
,但无论我做什么,都无法获得我想要的结果。
英文:
Trying to debug a file-transfer operation. Basically, I want PowerShell to merge two folders ($sourceDir and $targetDir), and rename any files in $sourceDir that already exist in $targetDir. It sort of does that, but instead of preserving the directory structure of the source folder, it's moving all the files from the source directory into the root of the target.
I know that adding the -Container flag on a standard Move-Item will force it to reconstruct the directory structure, but I've tried adding that here and I get errors.
This is what I have:
$sourceDir = "E:\Folder1"
$targetDir = "W:\Folder1"
Get-ChildItem -Path $sourceDir -Recurse | ForEach-Object {
$num=1
$nextName = Join-Path -Path $targetDir -ChildPath $_.name
while(Test-Path -Path $nextName)
{
$nextName = Join-Path $targetDir ($_.BaseName + "_$num" + $_.Extension)
$num+=1
}
$_ | Move-Item -Destination $nextName -Verbose
}
I've inserted write-host lines into it right above the Move-Item command and I can confirm it's targeting the root directory of the destination instead of maintaining the directory structure from the source. I've tried changing Get-ChildItem -Path
to -LiteralPath
, I've tried adding | % { $_.FullName } |
after the GCI, but no matter what I do the result I get is something different than what I'm looking for.
答案1
得分: 1
所有文件都被重新定位到目标目录的根目录,因为脚本只使用文件名创建目标路径。您必须在目标路径中包含子目录路径,以保持源文件夹的目录结构。
脚本已被更改,应该仍然保持目录结构,如下所示:
$sourceDir = "E:\Folder1"
$targetDir = "W:\Folder1"
Get-ChildItem -Path $sourceDir -Recurse | ForEach-Object {
$relativePath = $_.FullName.Substring($sourceDir.Length)
$nextName = Join-Path -Path $targetDir -ChildPath $relativePath
$num = 1
while(Test-Path -Path $nextName)
{
$nextName = Join-Path $targetDir ($relativePath + "_$num" + $_.Extension)
$num += 1
}
$_ | Move-Item -Destination $nextName -Verbose
}
通过从文件的完整路径中减去源目录路径的长度,脚本首先确定每个文件的相对路径。然后使用相对路径构建目标路径。
英文:
All files are being relocated to the root of the target directory because the script only uses the file name to create the destination path. You must include the subdirectory path in the destination path in order to maintain the directory structure of the source folder.
The script has been changed, and it should still maintain the directory structure, as follows:
$sourceDir = "E:\Folder1"
$targetDir = "W:\Folder1"
Get-ChildItem -Path $sourceDir -Recurse | ForEach-Object {
$relativePath = $_.FullName.Substring($sourceDir.Length)
$nextName = Join-Path -Path $targetDir -ChildPath $relativePath
$num = 1
while(Test-Path -Path $nextName)
{
$nextName = Join-Path $targetDir ($relativePath + "_$num" + $_.Extension)
$num += 1
}
$_ | Move-Item -Destination $nextName -Verbose
}
By deducting the length of the source directory path from the complete path of the file, the script first determines the relative path of each file. The target path is then built using the relative path.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论