Powershell 单驱动器迁移
我正在尝试将文件服务器迁移到一个驱动器。问题是,有许多文件夹和文件具有特殊字符,如“|”,”错误是正常的,如果您没有理由重命名该目录或文件,因为文件名正常且无需修改字符,则名称保持不变,因此,将显示一个错误,说明您无法重命名具有相同名称的文件/目录 尽管存在此错误,但该过程不会停止,对最终结果没有影响 我建议您将所有耦合键设置为搜索,对象中的新值:Powershell 单驱动器迁移,powershell,rename,onedrive,Powershell,Rename,Onedrive,我正在尝试将文件服务器迁移到一个驱动器。问题是,有许多文件夹和文件具有特殊字符,如“|”,”错误是正常的,如果您没有理由重命名该目录或文件,因为文件名正常且无需修改字符,则名称保持不变,因此,将显示一个错误,说明您无法重命名具有相同名称的文件/目录 尽管存在此错误,但该过程不会停止,对最终结果没有影响 我建议您将所有耦合键设置为搜索,对象中的新值: #add your template to replace $r = @{ ":" = "-"
#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
}
}
#添加要替换的模板
$r=@{
":" = "-"
“您运行10行代码,每行仅重命名一种类型的匹配项,但实际上您运行了10次相同的循环,在这种情况下,您的代码每次都尝试重命名所有文件夹,但在尝试使用相同的newName
重命名文件夹时出错,因为rename Item
尝试重命名它,即使新名称为它和旧的一样,似乎没有验证程序
在这种情况下,“最便宜”的解决方案是添加-ErrorAction SilentlyContinue
。但更复杂的解决方案是使用if
语句或更适合这种情况的开关来验证数据集
更新: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
}
}
}
$allFolders=Get ChildItem-Directory-Recurse
foreach($allFolders中的文件夹){
开关-Regex($folder.Name){
'[:?\|]'{
$newName=$folder.Name.replace(“[:?\ \ \ \”],“-”)
重命名项-Path$folder.FullName-NewName$NewName
}
'\*'{
$regexFormat='\*'
$matchNumber=[regex]::匹配($folder.Name,$regexFormat)| ForEach对象{$\u.value}
$newName=$folder.Name.replace(“*”,$matchNumber.Count)
重命名项-Path$folder.FullName-NewName$NewName
}
}
}
这样,您将运行1个循环而不是10个循环,并且您只尝试重命名与您提供的模式匹配的项目,因此与您正在使用的多行代码相比,您将看到显著的性能提高。在我的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-File)| ForEach对象{
$124;重命名项-新名称{
#用找到的连续星号数替换“*”
$name=$\名称
$match=([regex]'(\*+)).match($name)
while($match.Success){
$name=$name-replace[regex]::转义($match),$match.Length
$match=$match.NextMatch()
}
#最后用连字符替换其他特殊字符
$name-替换“[:?/|]”,“-”
}
}
Get ChildItem周围的括号强制它在管道重命名之前完成收集。否则,您可能会尝试重命名已处理的项目。-Path$\PSPath
->-LiteralPath$\PSPath
仍有此错误:…curse |%{重命名项-LiteralPath$\uu0.PSPath-NewName$\u0.Name.repla…\124~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~源路径和目标路径必须不同。
根据屏幕截图中提供的数据集,使用通配符*
的代码将无法运行,有非常好的测试下面答案中的示例。这确实有效,但我必须以不同的方式创建Hashmap,因为我每次都需要保持相同的顺序:$r=New Object System.Collections.Specialized.OrderedDictionary $r、 添加(“:”,“-”;$r.Add(“
$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
}
}
}
(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 '[:<>?/|]', '-'
}
}