我有几个文件,其名称包含各种 Unicode 字符。我想将它们重命名为仅包含“可打印”的 ASCII 字符 (32-126)。
例如,
Läsmig.txt //Before
L_smig.txt //After
Mike’s Project.zip
Mike_s Project.zip
或者为了获得加分,转录到最接近的字符
Läsmig.txt
Lasmig.txt
Mike’s Project.zip
Mike's Project.zip
理想情况下,寻找不需要第三方工具的答案。
(编辑:鼓励使用脚本;我只是想避免使用需要安装才能运行的小众共享软件应用程序)
Power shell 代码片段可以找到我想要重命名的文件:
gci -recurse | 其中 {$_.Name -match “[^\u0020-\u007E]”}
未回答的类似 Python 问题 -https://stackoverflow.com/questions/17870055/how-to-rename-a-file-with-non-ascii-character-encoding-to-ascii
答案1
我找到了类似的主题这里在 Stack Overflow 上。
使用以下代码,大多数字符将被翻译为它们的“最接近的字符”。虽然我无法获得翻译’
。(也许可以,但我无法用它在提示符中创建文件名;)ß
也无法翻译。
function Remove-Diacritics {
param ([String]$src = [String]::Empty)
$normalized = $src.Normalize( [Text.NormalizationForm]::FormD )
$sb = new-object Text.StringBuilder
$normalized.ToCharArray() | % {
if( [Globalization.CharUnicodeInfo]::GetUnicodeCategory($_) -ne [Globalization.UnicodeCategory]::NonSpacingMark) {
[void]$sb.Append($_)
}
}
$sb.ToString()
}
$files = gci -recurse | where {$_.Name -match "[^\u0020-\u007F]"}
$files | ForEach-Object {
$newname = Remove-Diacritics $_.Name
if ($_.Name -ne $newname) {
$num=1
$nextname = $_.Fullname.replace($_.Name,$newname)
while(Test-Path -Path $nextname)
{
$next = ([io.fileinfo]$newname).basename + " ($num)" + ([io.fileinfo]$newname).Extension
$nextname = $_.Fullname.replace($_.Name,$next)
$num+=1
}
echo $nextname
ren $_.Fullname $nextname
}
}
编辑:
我添加了一些代码来检查文件名是否已经存在,如果存在(1)
,则添加(2)
等。(它不够智能,无法检测到(1)
文件名中已经存在的要重命名的内容,因此在这种情况下您会得到(1) (1)
。但一如既往……一切都是可编程的;)
编辑2:
这是今晚的最后一个……
这个函数具有替换字符的不同功能。还添加了一行来将未知字符(例如ß
和)更改┤
为_
。
function Convert-ToLatinCharacters {
param([string]$inputString)
[Text.Encoding]::ASCII.GetString([Text.Encoding]::GetEncoding("Cyrillic").GetBytes($inputString))
}
$files = gci -recurse | where {$_.Name -match "[^\u0020-\u007F]"}
$files | ForEach-Object {
$newname = Convert-ToLatinCharacters $_.Name
$newname = $newname.replace('?','_')
if ($_.Name -ne $newname) {
$num=1
$nextname = $_.Fullname.replace($_.Name,$newname)
while(Test-Path -Path $nextname)
{
$next = ([io.fileinfo]$newname).basename + " ($num)" + ([io.fileinfo]$newname).Extension
$nextname = $_.Fullname.replace($_.Name,$next)
$num+=1
}
echo $nextname
ren $_.Fullname $nextname
}
}
答案2
我相信这会起作用...
$Files = gci | where {$_.Name -match "[^\u0020-\u007F]"}
$Files | ForEach-Object {
$OldName = $_.Name
$NewName = $OldName -replace "[^\u0020-\u007F]", "_"
ren $_ $NewName
}
但是我没有那么多 ASCII 文件名可供测试。