Как я могу исправить испорченные имена файлов shift-JIS?
У меня есть несколько файлов с именами shift-jis в ANSI. например
home_03@‚¢ƒgƒ‰ƒ“ƒNŠJ‚¢‚½Aƒtƒ@ƒCƒ‹—L‚è
когда они должны быть в Shift-Jis, как
home_03@青いトランク開いた、ファイル有り
Это потому что архиватор, который я использую, не поддерживает shift-jis. С этим ничего не поделаешь. Но есть ли способ исправить имена файлов файлов, которые я извлек?
редактировать:
другой пример
Ší‹ï‘ä@ƒXƒpƒi
должно быть
器具台@スパナ
1 ответ
Поскольку вы используете 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 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 считает недействительными в именах файлов вашего источника или назначения. Особенно в имени исходного файла, поскольку ваш инструмент извлечения, вероятно, мог бы безвозвратно исказить имя при извлечении (удалив байты, соответствующие недопустимым символам, таким как ?
или же \
в неправильной кодировке). Единственное, что вы можете сделать в этих случаях, это использовать альтернативный инструмент извлечения, который полностью устраняет эту проблему.