【问题标题】:One Drive MigrationOnedrive 迁移
【发布时间】:2021-07-31 18:50:45
【问题描述】:

我正在尝试将文件服务器迁移到 One Drive,问题是有许多文件夹和文件带有特殊字符,例如“|” , '

而且出于某种原因,该公司使用“*”进行版本控制,例如:

'*' => v.1
'**' => v.2

等等……

所以我写了一个 Powershell 脚本来重命名所有包含特殊字符的文件和文件夹。

#Files
Get-ChildItem -File -Recurse | % { Rename-Item -Path $_.PSPath -NewName $_.Name.replace(":","-")}
Get-ChildItem -File -Recurse | % { Rename-Item -Path $_.PSPath -NewName $_.Name.replace("<","-")}
Get-ChildItem -File -Recurse | % { Rename-Item -Path $_.PSPath -NewName $_.Name.replace(">","-")}
Get-ChildItem -File -Recurse | % { Rename-Item -Path $_.PSPath -NewName $_.Name.replace("?","-")}
Get-ChildItem -File -Recurse | % { Rename-Item -Path $_.PSPath -NewName $_.Name.replace("/","-")}
Get-ChildItem -File -Recurse | % { Rename-Item -Path $_.PSPath -NewName $_.Name.replace("|","-")}
Get-ChildItem -File -Recurse | % { Rename-Item -Path $_.PSPath -NewName $_.Name.replace("**********","10")}
Get-ChildItem -File -Recurse | % { Rename-Item -Path $_.PSPath -NewName $_.Name.replace("*********","9")}
Get-ChildItem -File -Recurse | % { Rename-Item -Path $_.PSPath -NewName $_.Name.replace("********","8")}
Get-ChildItem -File -Recurse | % { Rename-Item -Path $_.PSPath -NewName $_.Name.replace("*******","7")}
Get-ChildItem -File -Recurse | % { Rename-Item -Path $_.PSPath -NewName $_.Name.replace("******","6")}
Get-ChildItem -File -Recurse | % { Rename-Item -Path $_.PSPath -NewName $_.Name.replace("*****","5")}
Get-ChildItem -File -Recurse | % { Rename-Item -Path $_.PSPath -NewName $_.Name.replace("****","4")}
Get-ChildItem -File -Recurse | % { Rename-Item -Path $_.PSPath -NewName $_.Name.replace("***","3")}
Get-ChildItem -File -Recurse | % { Rename-Item -Path $_.PSPath -NewName $_.Name.replace("**","2")}
Get-ChildItem -File -Recurse | % { Rename-Item -Path $_.PSPath -NewName $_.Name.replace("*","1")}


#Directories
Get-ChildItem -Directory -Recurse | % { Rename-Item -Path $_.PSPath -NewName $_.Name.replace(":","-")}
Get-ChildItem -Directory -Recurse | % { Rename-Item -Path $_.PSPath -NewName $_.Name.replace("<","-")}
Get-ChildItem -Directory -Recurse | % { Rename-Item -Path $_.PSPath -NewName $_.Name.replace(">","-")}
Get-ChildItem -Directory -Recurse | % { Rename-Item -Path $_.PSPath -NewName $_.Name.replace("?","-")}
Get-ChildItem -Directory -Recurse | % { Rename-Item -Path $_.PSPath -NewName $_.Name.replace("/","-")}
Get-ChildItem -Directory -Recurse | % { Rename-Item -Path $_.PSPath -NewName $_.Name.replace("|","-")}
Get-ChildItem -Directory -Recurse | % { Rename-Item -Path $_.PSPath -NewName $_.Name.replace("**********","10")}
Get-ChildItem -Directory -Recurse | % { Rename-Item -Path $_.PSPath -NewName $_.Name.replace("*********","9")}
Get-ChildItem -Directory -Recurse | % { Rename-Item -Path $_.PSPath -NewName $_.Name.replace("********","8")}
Get-ChildItem -Directory -Recurse | % { Rename-Item -Path $_.PSPath -NewName $_.Name.replace("*******","7")}
Get-ChildItem -Directory -Recurse | % { Rename-Item -Path $_.PSPath -NewName $_.Name.replace("******","6")}
Get-ChildItem -Directory -Recurse | % { Rename-Item -Path $_.PSPath -NewName $_.Name.replace("*****","5")}
Get-ChildItem -Directory -Recurse | % { Rename-Item -Path $_.PSPath -NewName $_.Name.replace("****","4")}
Get-ChildItem -Directory -Recurse | % { Rename-Item -Path $_.PSPath -NewName $_.Name.replace("***","3")}
Get-ChildItem -Directory -Recurse | % { Rename-Item -Path $_.PSPath -NewName $_.Name.replace("**","2")}
Get-ChildItem -Directory -Recurse | % { Rename-Item -Path $_.PSPath -NewName $_.Name.replace("*","1")}

所以这很好,但由于某种原因,即使它有效,我在重命名文件夹时也会遇到很多错误......

错误:

 … curse | % { Rename-Item -Path $_.PSPath -NewName $_.Name.replace("*", …
     |                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     | Source and destination path must be different.

我也试过这个帖子suggest,但这对我不起作用:

有人知道我为什么会收到此错误吗?以及如何解决?

提前致谢。

【问题讨论】:

  • -Path $_.PSPath -> -LiteralPath $_.PSPath
  • 仍然出现此错误:… curse | % { Rename-Item -LiteralPath $_.PSPath -NewName $_.Name.repla … | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | Source and destination path must be different.
  • 根据您在屏幕截图中提供的数据集,您的带有通配符* 字符的代码将不起作用,下面的答案中有很好的示例。

标签: powershell rename onedrive


【解决方案1】:

您运行 10 行代码来重命名每行仅一种类型的匹配项,但实际上您运行了 10 次相同的循环,在这种情况下,您的代码尝试每次重命名所有文件夹,但在尝试重命名时会出错使用相同的 newName 重命名文件夹,因为即使新名称与旧名称相同,Rename-Item 也会尝试重命名它,它似乎没有验证器。

在这种情况下,“最便宜”的解决方案是添加 -ErrorAction SilentlyContinue 。但更复杂的解决方案是使用if 语句或更适合switch 的情况来验证您的数据集。

更新:Regex 可能不是最容易处理的事情,因此下面的示例也说明了通配符 * 字符。

$allFolders=Get-ChildItem -Directory -Recurse

foreach($folder in $allFolders){
    
    switch -Regex ($folder.Name){
        '[:<>?\|]'{
            $newName=$folder.Name.replace("[:<>?\|]","-")
            Rename-Item -Path $folder.FullName -NewName $newName 
        }
        '\*'{
            $regexFormat = '\*'
            $matchNumber=[regex]::Matches($folder.Name, $regexFormat) | ForEach-Object { $_.value }

            $newName=$folder.Name.replace("*",$matchNumber.Count)
            Rename-Item -Path $folder.FullName -NewName $newName 

        }
    }
}

这样,您将运行 1 个循环而不是 10 个循环,并且您只尝试重命名与您提供的模式匹配的项目,因此与您使用的多行代码相比,您将看到性能显着提高。

【讨论】:

    【解决方案2】:

    这个错误是正常的,如果你没有理由重命名目录或文件,因为文件名是好的并且没有字符可以修改,名称保持不变,所以会显示一个错误,说你不能用相同的方式重命名文件/目录名字。

    尽管出现此错误,但进程并未停止,对最终结果没有影响

    我建议您将所有配对键设置为搜索,对象中的新值:

    #add your template to replace
    $r = @{
        ":" = "-"
        "<" = "-"
        "**********" = "10";
        "*********" = "9";
        "********" = "8"
        }
    
    $Folders=Get-ChildItem -Directory -path -Recurse
    
    foreach($folder in $Folders){
        $newname = $folder.Name
    
        foreach($k in $r.Keys){
             $newname = $newname.Replace($k,$r.$k) 
        }
    
        #rename only if original name and newname are differents
        if(!$newname.equals($folder.Name)){
            Rename-Item -Path $folder.FullName -NewName $newname
        }
    }
    

    为你的文件做同样的事情......

    【讨论】:

    • 这确实有效,但我必须以不同的方式创建 Hashmap,因为我每次都需要保持相同的顺序:$r = New-Object System.Collections.Specialized.OrderedDictionary ​ $r.Add(":", "-"); $r.Add("&lt;", "-");
    【解决方案3】:

    在我的 Windows 机器上,我不能在文件或文件夹名称中包含类似的字符,但理论上这应该可以:

    (Get-ChildItem -File) | ForEach-Object {
        $_ | Rename-Item -NewName {
            # replace the '*' by the number of consecutive asterikses found
            $name = $_.Name
            $match = ([regex] '(\*+)').Match($name)
            while ($match.Success) {
                $name = $name -replace [regex]::Escape($match), $match.Length
                $match = $match.NextMatch()
            } 
            # finally replace the other special characters by a hyphen
            $name -replace '[:<>?/|]', '-' 
        }
    }
    

    Get-ChildItem 周围的括号强制它在管道重命名之前完成收集。否则,您最终可能会尝试重命名已处理的项目

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-06-22
      • 2017-06-26
      • 2019-12-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-01
      • 1970-01-01
      相关资源
      最近更新 更多