Переименовать родителей с PowerShell - PullRequest
0 голосов
/ 21 марта 2019

У меня есть C: \ test1 \ test2 \ test3 \ test4 \ test5 \ test6 \ test7 \ test8

Мне нужно переименовать каждую папку пути, начиная с последней (test8), до первой (test1).Я должен протестировать в Windows 10 папки с максимальным именем и для этого мне нужно сначала изменить имя последней папки (test8), а затем ее родитель (test7).

У меня есть эта функция

[CmdletBinding()]
param(
    [string]$path
)


function createFolderStructure{

        $parentName = "F:\"
        $name = "ThisFolderHas256Characters_ThisFolderHas256Characters_"+
                "ThisFolderHas256Characters_ThisFolderHas256Characters_"+
                "ThisFolderHas256Characters_ThisFolderHas256Characters_"+
                "ThisFolderHas256Characters_ThisFolderHas256Characters_"+
                "ThisFolderHas256Characters_ThisFolderHas"

        for ($i=0; $i -lt 10; $i++){
            $parentName += "test\";
            New-Item "$parentName" -ItemType Directory;
        }

        Get-ChildItem -Path "F:\test" -Recurse -Force | ForEach-Object{
                Rename-Item -Path $_.fullname -NewName $name
            }
     }



createFolderStructure

Но я понятия не имею, как сделать так, чтобы элемент прошел снизу вверх.Как он у меня есть, он не работает, так как он переходит из первой папки в последнюю, а во второй папке я получаю исключение имени, слишком длинное для пути.Есть идеи ??

Ответы [ 2 ]

0 голосов
/ 21 марта 2019

Во-первых, как вы заметили, существуют ограничения для персонажей. Общая длина пути не может превышать 256 символов для любого файла в последнем каталоге, а длина каталога не может превышать 248 символов. Вы хотите добавить некоторые проверки для этого. Вначале это означает, что имя папки из 256 символов никогда не должно работать. Когда-либо.

Если вы знаете, что такое полный путь, и просто хотите пройти вверх по структуре каталогов к корневой папке, вы можете использовать свойство .Parent для объекта папки.

Ниже приведено лишь подтверждение концепции, которая создаст структуру папок с вложенным в нее файлом, а затем с учетом начальной и конечной точки будет работать из самой глубокой вложенной папки, указанной в целевой папке, переименовывая папки в это продолжается до тех пор, пока не достигнет ограничения по длине.

$NewName = 'ReallyExtremelyLongFolderName'
Remove-Item C:\Test -Recurse -Force -ea 0
Remove-Item "C:\$NewName" -Recurse -Force -ea 0

$RootFolder = "C:\test"
$TargetFolder = 'C:\test\Test\Test\Test\Test\Test\Test\Test\test'
New-Item "C:\test\Test\Test\Test\Test\Test\Test\Test\test\Test\Some Long File.xlsx" -force |Out-Null
$LongestFileName = Get-ChildItem $TargetFolder -recurse | Sort {$_.FullName.Length} | Select -last 1 -ExpandProperty FullName
$MaxLength = If((Get-Item $LongestFileName).PSIsContainer){248}Else{256}
$CurrentFolder = Get-Item $TargetFolder
$NewTarget = $TargetFolder
$VerbosePreference='Continue'
Do{
    Write-Verbose "Working on:                $($CurrentFolder.FullName)"
    $NewTargetTmp = $NewTarget.Replace($CurrentFolder.FullName,(Join-Path (split-path $CurrentFolder.FullName) $NewName))
    #Check new path for existing longest path
    Write-Verbose "Checking new longest path: $($LongestFileName.Replace($NewTarget,$NewTargetTmp))`nLength: $($LongestFileName.Replace($NewTarget,$NewTargetTmp).length)`n"
    If(($LongestFileName=$LongestFileName.Replace($NewTarget,$NewTargetTmp)).Length -gt $MaxLength) {Write-Warning "New target path to deepest nested file/folder too long:`n$LongestFileName";break}
    $CurrentFolder | Rename-Item -NewName $NewName
    $NewTarget = $NewTargetTmp
    $CurrentFolder = Get-Item $CurrentFolder.Parent.FullName
}Until($CurrentFolder.FullName -eq $RootFolder)
$VerbosePreference='SilentlyContinue'

Вы можете закомментировать $VerbosePreference строк (есть 2 из них), чтобы сделать это менее спам.

0 голосов
/ 21 марта 2019

Вы можете сделать это рекурсивно с помощью функции.Я думаю, что вам может понадобиться сократить переменную $ name хотя:

Function Rename-Folders {
param([string]$path)

$name = "ThisFolderHas256Characters_ThisFolderHas256Characters_"+
                "ThisFolderHas256Characters_ThisFolderHas256Characters_"+
                "ThisFolderHas256Characters_ThisFolderHas256Characters_"+
                "ThisFolderHas256Characters_ThisFolderHas256Characters_"+
                "ThisFolderHas256Characters_ThisFolderHas"

if ($path -match "$($path | split-path -qualifier)\\?$") {
return
}
Get-Item -path $path | Rename-Item -NewName $name
Rename-Folders -path ($path | split-path)
}

$path = "F:\test1\test2\test3\test4"
Rename-Folders $path
...