Поскольку вы используете Windows, PowerShell, вероятно, самый простой способ.
Теперь PowerShell внутренне использует UTF-16 для своих строк, поэтому преобразование будет включать четыре шага:
- Считать неверное имя файла из файловой системы в PS (внутренне представленный в виде строки UTF-16)
- Скажите PS преобразовать строку в необработанный байтовый массив, как если бы строка была <неправильная кодировка>. Мы не можем использовать строку PS напрямую (так как это UTF-16).
- Скажите PS преобразовать байтовый массив обратно в строку, интерпретирующую его как <правильная кодировка>. Это даст использование строки UTF-16 необработанных байтов, интерпретируемых как Shift-JIS.
- Переименовать файл
Давайте начнем с определения кодировок. В вашем случае, я предполагаю, что ваш источник - Windows-1252 (кодовая страница не-Unicode по умолчанию для западной / английской Windows).
$srcEnc = [System.Text.Encoding]::GetEncoding("Windows-1252")
$destEnc = [System.Text.Encoding]::GetEncoding("Shift-JIS")
Вы также можете использовать [System.Text.Encoding]::Default
чтобы получить текущую системную кодовую страницу, но я предпочитаю быть явным.
Затем мы применяем шаги преобразования:
$newName = $destEnc.GetString($srcEnc.GetBytes($oldName))
В вашем примере home_03@‚¢ƒgƒ‰ƒ“ƒNŠJ‚¢‚½Aƒtƒ@ƒCƒ‹—L‚è
становится home_03@ツいトランク開いたAファイル有り
. Хотя это отличается от вашего примера (см. Примечания внизу), оно соответствует тому, что я получаю с http://string-functions.com/encodedecode.aspx's Windows-1252 => Shift-JIS. Если это неверно, возможно, вам придется поиграться, пока не найдете правильные кодировки источника и назначения.
Собираем его вместе со стандартным циклом:
$srcEnc = [System.Text.Encoding]::GetEncoding("Windows-1252")
$destEnc = [System.Text.Encoding]::GetEncoding("Shift-JIS")
Get-ChildItem | %{Rename-Item -LiteralPath "$_" "$($destEnc.GetString($srcEnc.GetBytes($_.Name)))"}
Или, если вы предпочитаете переходить в подкаталоги:
$srcEnc = [System.Text.Encoding]::GetEncoding("Windows-1252")
$destEnc = [System.Text.Encoding]::GetEncoding("Shift-JIS")
Get-ChildItem -Recurse | %{Rename-Item -LiteralPath "$_" "$($destEnc.GetString($srcEnc.GetBytes($_.Name)))"}
Добавьте -File
в Get-ChildItem
если вы хотите избежать переименования каталогов.
Похоже, ваш пример включает в себя два символа, которые были недопустимы в Windows-1252 и, вероятно, были отброшены при публикации вопроса (на основе изменения процесса с использованием выходных данных вашего примера). Между первыми 144
и 0x90
есть @
(Â
), а между 129
и 0x81
- ½
(A
). Для удобства всех, кто хочет проверить, вот кодированная версия base64 необработанных байтов: aG9tZV8wM0CQwoKig2eDiYOTg06KSoKigr2BQYN0g0CDQ4OLl0yC6A==
.
Также обратите внимание, что это не будет работать, если есть символы, которые Windows считает недействительными в именах файлов вашего источника или назначения. Особенно в имени исходного файла, поскольку ваш инструмент извлечения, вероятно, мог бы безвозвратно исказить имя при извлечении (удалив байты, соответствующие недопустимым символам вроде ?
или \
в неправильной кодировке). Единственное, что вы можете сделать в этих случаях, это использовать альтернативный инструмент извлечения, который полностью устраняет эту проблему.