Кодирование пакетного файла
Я хотел бы иметь дело с именем файла, содержащим странные символы, например, французский é.
Все отлично работает в оболочке:
C:\somedir\>ren -hélice hélice
Я знаю, если я поместил эту строку в .bat файл, я получаю следующий результат:
C:\somedir\>ren -hÚlice hÚlice
Видите? é были заменены на Ú.
То же самое верно для вывода команды. Если я dir
некоторая директория в оболочке, вывод будет прекрасным. Если я перенаправляю этот вывод в файл, некоторые символы преобразуются.
Итак, как я могу сказать cmd.exe, как интерпретировать то, что отображается как é в моем командном файле, действительно является é, а не Ú или запятой?
Таким образом, при запуске файла .bat нет способа дать подсказку о кодовой странице, в которой она была написана?
Ответы
Ответ 1
Вы должны сохранить пакетный файл с OEM-кодировкой. Как это сделать, зависит от вашего текстового редактора. Используемая в этом случае кодировка также меняется. Для западных культур это обычно CP850.
Пакетные файлы и кодировка - это действительно две вещи, которые не особенно похожи друг на друга. Вы заметите, что Unicode также невозможно использовать там, к сожалению (хотя переменные среды обрабатывают это нормально).
В качестве альтернативы вы можете настроить консоль на использование другой кодовой страницы:
chcp 1252
должен сделать трюк. По крайней мере, это сработало для меня здесь.
Когда вы выполняете перенаправление вывода, например, с помощью dir
, применяются те же правила. Используется кодовая страница окна консоли. Вы можете использовать переключатель /u
для cmd.exe
, чтобы принудительно перенаправить выход Юникода, что приводит к тому, что результирующие файлы находятся в UTF-16.
Что касается кодировок и кодовых страниц в cmd.exe
в целом, также см. этот вопрос:
РЕДАКТИРОВАТЬ: Что касается вашего редактирования: Нет, cmd
всегда предполагает, что командный файл должен быть записан в кодовой странице консоли по умолчанию. Однако вы можете легко включить chcp
в начале пакета:
chcp 1252>NUL
ren -hélice hélice
Чтобы сделать это более надежным при использовании непосредственно из командной строки, вы можете захотеть запомнить старую кодовую страницу и впоследствии ее восстановить:
@echo off
for /f "tokens=2 delims=:." %%x in ('chcp') do set cp=%%x
chcp 1252>nul
ren -hélice hélice
chcp %cp%>nul
Ответ 2
Я создал следующий блок, который я поставил в начале моих пакетных файлов:
set Filename=%0
IF "%Filename:~-8%" == "-850.bat" GOTO CONVERT_CODEPAGE_END
rem Converting code page from 1252 to 850.
rem My editors use 1252, my batch uses 850.
rem We create a converted -850.bat file, and then launch it.
set File850=%~n0-850.bat
PowerShell.exe -Command "get-content %0 | out-file -encoding oem -filepath %File850%"
call %File850%
del %File850%
EXIT /b 0
:CONVERT_CODEPAGE_END
Ответ 3
У меня были проблемы с этим, и вот решение, которое я нашел. Найдите десятичное число для символа, который вы ищете на текущей кодовой странице.
Например, я в кодексе 437 (chcp
говорит вам), и мне нужен знак степени. http://en.wikipedia.org/wiki/Code_page_437 сообщает мне, что знак степени - номер 248.
Затем вы найдете символ Unicode с тем же номером.
Символ Юникода в 248 (U + 00F8) есть.
Если вы введете символ Unicode в пакетный script, он отобразит консоль в качестве желаемого символа.
Итак, мой командный файл
echo
печатает
°
Ответ 4
У меня были лаковые знаки внутри кода в R (например, ą, ę, ź, ż и т.д.) и была проблема при запуске этого R script с .bat файлом (в выходной файл .Rout вместо этих знаков были такие, как%, &, # и т.д., и код не работал до конца).
Мое решение:
- Сохранить R script с кодировкой: Файл > Сохранить с кодировкой > CP1250
- Запустить файл .bat
Это сработало для меня, но если есть проблема, попробуйте использовать другие кодировки.
Ответ 5
Мне нравятся три понятия:
-
Кодирование выходной консоли
-
Внутренняя кодировка командной строки (которая была изменена с помощью chcp)
-
.bat Текстовое кодирование
Самый простой сценарий для меня: у меня будут первые два упомянутых в той же кодировке, скажем, CP850, и я буду хранить мой .bat в той же кодировке (в Notepad ++, меню Кодирование → Наборы символов → Западноевропейский → OEM 850).
Но предположим, что кто-то вручает мне .bat в другой кодировке, скажем CP1252 (в Notepad ++, меню Кодировка * → Наборы символов → Западноевропейская → Windows-1252)
Затем я бы изменил внутреннюю кодировку командной строки с помощью chcp 1252.
Это изменяет кодировку, которую он использует, чтобы разговаривать с другими процессами, ни входное устройство, ни выходная консоль.
Таким образом, мой экземпляр командной строки будет эффективно отправлять символы в 1252 через дескриптор файла STDOUT, но текст gabbed появляется, когда консоль декодирует их как 850 (é is Ú).
Затем я изменяю файл следующим образом:
@echo off
perl -e "use Encode qw/encode decode/;" -e "print encode('cp850', decode('cp1252', \"ren -hlice hlice\n\"));"
ren -hlice hlice
Сначала я включаю эхо-сигнал, поэтому команды не выводятся, если явно не выполняется либо эхо... или perl -e "print..."
Затем я помещаю этот шаблон каждый раз, когда мне нужно вывести что-то
perl -e "использовать Encode qw/encode decode/;" -e "print encode ('cp850', decode ('cp1252', \" ren -hélice hélice\n\ "));"
Я заменю фактический текст, который я покажу для этого: ren -hélice hélice.
И также мне нужно было бы заменить мою консольную кодировку для cp850 и другой боковой кодировки для cp1252.
И чуть ниже я поставлю желаемую команду.
Я сломал проблематичную строку на половину вывода и действительную половину команды.
-
Первое, что я делаю наверняка: "é" интерпретируется как "é" посредством транскодирования. Это необходимо для всех выходных предложений, поскольку консоль и файл находятся в разных кодировках.
-
Вторая, настоящая команда (пропущенная с @echo off), зная, что мы имеем одинаковую кодировку как из chcp, так и для .bat-текста достаточно для обеспечения правильной интерпретации символов.