Как рекурсивно переименовать папки с помощью Powershell? - PullRequest
9 голосов
/ 02 июня 2011

Рекурсивное переименование файлов с использованием PS тривиально (отличие от примера из блога Майка Ормонда ):

dir *_t*.gif -recurse 
    | foreach { move-item -literal $_ $_.Name.Replace("_thumb[1]", "")}

Я пытаюсь рекурсивно переименовать структуру папок.

Вариант использования: я хотел бы иметь возможность переименовать все решение VS.NET (например, из Foo.Bar в Bar.Foo). Для этого есть несколько шагов:

  1. Переименование папок (например, \ Foo.Bar \ Foo.Bar.Model => \ Bar.Foo \ Bar.Foo.Model)
  2. Переименование файлов (например, Foo.Bar.Model.csproj => Bar.Foo.Model.csproj)
  3. Поиск и замена в файлах для исправления изменений в пространстве имен (например, 'namespace Foo.Bar' => 'namespace Bar.Foo')

Я сейчас работаю над первым шагом в этом процессе.

Я нашел это сообщение , в котором говорится о проблемах и заявляет о решении, но не говорится о том, что это за решение.

Я продолжаю бежать в рекурсивную стену. Если я позволю PS справиться с рекурсией, используя флаг, родительская папка будет переименована перед дочерними, и скрипт выдаст ошибку. Если я попытаюсь реализовать рекурсию сам, у меня все болит, и все идет ужасно неправильно - ради жизни я не могу заставить вещи начинать свои переименования с хвоста дерева рекурсии.

Ответы [ 3 ]

8 голосов
/ 01 марта 2012

Вот решение, которое закончило rbellamy:

Get-ChildItem $Path -Recurse | %{$_.FullName} |
Sort-Object -Property Length -Descending |
% {
    Write-Host $_
    $Item = Get-Item $_
    $PathRoot = $Item.FullName | Split-Path
    $OldName = $Item.FullName | Split-Path -Leaf
    $NewName = $OldName -replace $OldText, $NewText
    $NewPath = $PathRoot | Join-Path -ChildPath $NewName
    if (!$Item.PSIsContainer -and $Extension -contains $Item.Extension) {
        (Get-Content $Item) | % {
            #Write-Host $_
            $_ -replace $OldText, $NewText
        } | Set-Content $Item
    }
    if ($OldName.Contains($OldText)) {
        Rename-Item -Path $Item.FullName -NewName $NewPath
    }
}
3 голосов
/ 02 июня 2011

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

например

gci <directory> -recurse |
 foreach {$_.fullname} |
  sort -length -desc
2 голосов
/ 02 июня 2011

Может быть, что-то в этом полезное, вот фрагмент кода, который повторяется и добавляется "pre" к структуре каталогов

$dirs = Get-ChildItem c:/foldertorecurse -rec |  Where-Object {$_.PSIsContainer -eq 1} |  sort fullname -descending
foreach ( $dir in $dirs ) { rename-item -path $dir.fullname -newname ("pre" + $dir.name) } 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...