Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/powershell/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用Powershell递归重命名文件夹?_Powershell_Recursion_File Rename - Fatal编程技术网

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

如何使用Powershell递归重命名文件夹?,powershell,recursion,file-rename,Powershell,Recursion,File Rename,使用PS递归重命名文件很简单(与示例不同): 我正在尝试递归重命名文件夹结构 用例是我希望能够重命名整个VS.NET解决方案(例如从Foo.Bar到Bar.Foo)。要做到这一点,有几个步骤: 重命名文件夹(例如。\Foo.Bar\Foo.Bar.Model=>\Bar.Foo\Bar.Foo.Model) 重命名文件(例如Foo.Bar.Model.csproj=>Bar.Foo.Model.csproj) 在文件中查找并替换以更正命名空间更改(例如“namespace Foo.Bar”=>“

使用PS递归重命名文件很简单(与示例不同):

我正在尝试递归重命名文件夹结构

用例是我希望能够重命名整个VS.NET解决方案(例如从Foo.Bar到Bar.Foo)。要做到这一点,有几个步骤:

  • 重命名文件夹(例如。\Foo.Bar\Foo.Bar.Model=>\Bar.Foo\Bar.Foo.Model)
  • 重命名文件(例如Foo.Bar.Model.csproj=>Bar.Foo.Model.csproj)
  • 在文件中查找并替换以更正命名空间更改(例如“namespace Foo.Bar”=>“namespace Bar.Foo”)
  • 我目前正在做这个过程的第一步

    我找到了一个帖子,它谈到了挑战,并声称有一个解决方案,但没有谈到解决方案是什么


    我一直遇到递归墙。如果我让PS使用标志处理递归,那么父文件夹将在子文件夹之前重命名,脚本将抛出一个错误。如果我自己尝试实现递归,我的脑袋会很痛,事情会变得非常糟糕——就我而言,我无法让事情从递归树的末尾开始重命名。

    这样如何-做一个全名的递归列表,按全名的长度降序排序,然后在重命名例程中运行该命令

    e、 g

    gci-递归|
    foreach{$\.fullname}|
    排序-长度-描述
    
    也许这里面有些有用的东西,下面是一个递归并在目录结构前面加上“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) } 
    

    以下是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
        }
    }
    

    我喜欢这个。稍微调整一下就可以了。你基本上拥有@mjolinir所拥有的,但是你拥有按全名排序的功能,这并不能正确地将排序按与层次结构中位置相反的顺序排列。很好,谢谢!在Get Items上使用-literalPath选项意味着不会解释路径或文件名中出现的任何符号。此外,订购我的全名长度并不是在所有情况下都有效。如果文件夹的长度相差很大,并且在较高路径之前重命名较低路径,脚本将报告无法找到文件/文件夹。它的路径会改变。
    $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) } 
    
    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
        }
    }