Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/solr/3.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_Rename_Onedrive - Fatal编程技术网

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 '[:<>?/|]', '-' 
    }
}