递归地用PowerShell替换符号

时间:2014-02-19 23:55:52

标签: powershell

我有一个我想要浏览的文件夹结构,只要文件夹名称包含“&”,我就想用“和”替换它。我认为这对PowerShell来说是可行的,但对于PowerShell来说,我是极端的noobie。

谢谢!

这是我的尝试:

get-childitem -recurse ./ *&* |  where-object { $_.Name -like "*&*" } | % {rename-item $_ -newname $_.Name.Replace("&","and") -whatif}

这只会更改文件夹名称吗?

也尝试了这个,但也没有运气(这个给出错误:无法重命名,因为指定的目标代表路径或设备名称:

gci -recurse | where-object { $_.Name -like "*&*" } | ?{ $_.PSIsContainer } | % {rename-item $_FullName $_FullName.Replace("&","and")}

编辑:Windows Server 2008 R2上的POWERSHELL

4 个答案:

答案 0 :(得分:2)

我怀疑原始代码失败的一个原因是因为Rename-Item被赋予一个NewName参数,该参数包含整个路径,而不仅仅是名称。这里的次要问题是代码将尝试从上到下重命名,这可能使管道中的其他对象无效。我试图通过首先处理最长的路径来解决这个问题(因此在PSPath.length上降序排序)。它适用于我的测试文件夹。

get-childitem ./ -Recurse -Filter "*&*" |
    ? { $_.PSIsContainer } |
    sort { ($_.PSPath).length } -Descending |
    % {
        $_ | Rename-Item -NewName ($_.Name -replace "&","and")
    }

答案 1 :(得分:1)

您的错误原因是您更换了&整个路径中的字符,甚至是父文件夹。

例如,假设您要将文件夹c:\me & my\something & another重命名为$ _。FullName.Replace(“&”,“和”)会将其更改为c:\me and my\something and another。但是,由于我们在这个小测试场景中将子文件夹重命名为父文件夹之前我们实际上正在尝试将移动该文件夹从c:\my & my的子文件移动到{{1}的子文件(最重要的是我们想将它移动到一个不存在的文件夹。

c:\me and my的帮助部分(我通过执行Rename-Item获得):

Get-Help Rename-Item -Parameter NewName

所以我们只想在Specifies the new name of the item. Enter only a name, not a path and name. If you enter a path that is different from the path that is specified in the Path parameter, Rename-Item generates an error. To rename and move an item, use the Move-Item cmdlet. 参数中包含文件夹的名称。

最后,正如@andyb指出的那样,我们还需要按子文件夹,然后是父文件夹的顺序重命名项目,以确保父路径仍然完好无损。 @ andyb建议的按NewName路径长度对文件夹进行排序的解决方案应该适用于此。

因此,以下内容应该能够很好地发挥作用。

FullName

编辑:更新以包括按文件夹路径长度降序排序,因为@andyb指出了一个错误。

答案 2 :(得分:0)

你走在正确的道路上。在'C:\ temp \ aaa'文件夹下创建了几个测试文件夹和文件,以显示它是如何工作的

PS C:\> gci C:\Temp\aaa -recurse | where {$_.name -match '&'} | Rename-Item -newname {$_.name -replace '&','and'} -whatif
What if: Performing the operation "Rename Directory" on target "Item: C:\Temp\aaa\ad & il Destination: C:\Temp\aaa\ad and il".
What if: Performing the operation "Rename Directory" on target "Item: C:\Temp\aaa\ad & il\hin\di&st&t Destination: C:\Temp\aaa\ad & il\hin\diandstandt".
What if: Performing the operation "Rename File" on target "Item: C:\Temp\aaa\ad & il\hin\adilll&hindist &an.txt Destination: C:\Temp\aaa\ad & il\hin\adilllandhi ndist andan.txt".

答案 3 :(得分:0)

<强>步骤: 1.匹配项目

  1. 反转项目,以便我们可以将它们从子级重命名为

  2. 重命名

  3. <强>代码:

    $matchedItems = ls D:\test -Recurse | where { $_.Name -like '*&*' }
    
    [array]::Reverse( $matchedItems )
    
     $matchedItems | foreach {
      $newName = ""
      if($_.PSIsContainer){
    
        $newName = Join-Path $_.Parent.FullName ($_.BaseName -replace '&' , 'and')
      }
      else {
    
        $newName = Join-Path $_.Directory.FullName ($_.BaseName -replace '&' , 'and')
      }
    
    
      $_ | Rename-Item -NewName $newName
     }
    

    <强>输出:

    PS C:\> ls D:\test -Recurse | select FullName
    
    FullName                                                                                                                
    --------                                                                                                                
    D:\test\& New Foder                                                                                                     
    D:\test\New & folder                                                                                                    
    D:\test\New folder&                                                                                                     
    D:\test\test & test.txt                                                                                                 
    D:\test\& New Foder\New & folder                                                                                        
    D:\test\& New Foder\New folder&                                                                                         
    D:\test\& New Foder\test & test.txt                                                                                     
    D:\test\New folder&\& New Foder                                                                                         
    D:\test\New folder&\New & folder                                                                                        
    D:\test\New folder&\New folder&                                                                                         
    D:\test\New folder&\test & test.txt                                                                                     
    D:\test\New folder&\& New Foder\New & folder                                                                            
    D:\test\New folder&\& New Foder\New folder&                                                                             
    D:\test\New folder&\& New Foder\test & test.txt                                                                         
    
    
    
    PS C:\> $matchedItems = ls D:\test -Recurse | where { $_.Name -like '*&*' }
    [array]::Reverse( $matchedItems )
    
     $matchedItems | foreach {
      $newName = ""
      if($_.PSIsContainer){
      $newName = Join-Path $_.Parent.FullName ($_.BaseName -replace '&' , 'and')
      }
      else {
    
      $newName = Join-Path $_.Directory.FullName ($_.BaseName -replace '&' , 'and')
      }
    
    
      $_ | Rename-Item -NewName $newName
     }
    
    
    
    PS C:\> ls D:\test -Recurse | select FullName
    
    FullName                                                                                                                
    --------                                                                                                                
    D:\test\and New Foder                                                                                                   
    D:\test\New and folder                                                                                                  
    D:\test\New folderand                                                                                                   
    D:\test\test and test                                                                                                   
    D:\test\and New Foder\New and folder                                                                                    
    D:\test\and New Foder\New folderand                                                                                     
    D:\test\and New Foder\test and test                                                                                     
    D:\test\New folderand\and New Foder                                                                                     
    D:\test\New folderand\New and folder                                                                                    
    D:\test\New folderand\New folderand                                                                                     
    D:\test\New folderand\test and test                                                                                     
    D:\test\New folderand\and New Foder\New and folder                                                                      
    D:\test\New folderand\and New Foder\New folderand                                                                       
    D:\test\New folderand\and New Foder\test and test