如何使用 Powershell 递归重命名文件夹?

发布于 2024-11-11 13:59:04 字数 859 浏览 8 评论 0原文

使用 PS 递归重命名文件很简单(来自 Mike Ormond 的博客):

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. 在文件中查找并替换以更正命名空间更改(例如“命名空间 Foo.Bar”=>“命名空间 Bar.Foo”)

我目前正在执行此过程的第一步。

我发现这篇帖子,其中讨论了挑战,并声称提供了解决方案,但没有谈论这个解决方案是什么。

我总是遇到递归墙。如果我让 PS 使用标志来处理递归,则父文件夹会在子文件夹之前重命名,并且脚本会引发错误。如果我尝试自己实现递归,我的头会很痛,事情会变得非常错误 - 在我的一生中,我无法让事物在递归树的尾部开始重命名。

Recursive renaming files using PS is trivial (variation on example from Mike Ormond's blog):

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

I'm trying to recursively rename a folder structure.

The use case is I'd like to be able to rename a whole VS.NET Solution (e.g. from Foo.Bar to Bar.Foo). To do this there are several steps:

  1. Rename folders (e.g. \Foo.Bar\Foo.Bar.Model => \Bar.Foo\Bar.Foo.Model)
  2. Rename files (e.g. Foo.Bar.Model.csproj => Bar.Foo.Model.csproj)
  3. Find and Replace within files to correct for namespace changes (e.g. 'namespace Foo.Bar' => 'namespace Bar.Foo')

I'm currently working the first step in this process.

I found this posting, which talks about the challenges, and claims a solution but doesn't talk about what that solution is.

I keep running into the recursion wall. If I let PS deal with the recursion using a flag, the parent folder gets renamed before the children, and the script throws an error. If I try to implement the recursion myself, my head get's all achy and things go horribly wrong - for the life of me I cannot get things to start their renames at the tail of the recursion tree.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

不顾 2024-11-18 13:59:04

这是 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
    }
}

Here's the solution rbellamy ended up with:

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
    }
}
安静 2024-11-18 13:59:04

怎么样 - 做一个全名的递归列表,按全名的长度降序排序,然后通过您的重命名例程运行它。

例如

gci <directory> -recurse |
 foreach {$_.fullname} |
  sort -length -desc

How about this - do a recursive list of the full names, sort it in descending order by the length of the full name, and then run that back through your rename routine.

e.g.

gci <directory> -recurse |
 foreach {$_.fullname} |
  sort -length -desc
猫烠⑼条掵仅有一顆心 2024-11-18 13:59:04

也许其中的某些内容很有用,这是一个递归并将“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) } 

Maybe something in this is useful, here's a snippet that recurses and prepends "pre" to a directory structure

$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) } 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文