如何:移动文件保留目录结构并重命名现有文件? (脚本调试)

huangapple go评论97阅读模式
英文:

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.

huangapple
  • 本文由 发表于 2023年3月7日 23:17:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/75663834.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定