batch file编码
我想处理包含奇怪字符的文件名,比如法文。
一切工作正常在shell:
C:\somedir\>ren -hélice hélice
我知道如果我把这一行放在一个.bat文件,我得到以下结果:
C:\somedir\>ren -hÚlice hÚlice
看? 已被Ú取代。
命令输出也是如此。 如果我在shell的目录,输出很好。 如果我将这个输出redirect到一个文件,一些字符就会被转换。
那么怎样才能告诉cmd.exe如何解释在我的batch file中显示为“é”,真的是é而不是Ú或逗号?
所以当执行一个.bat文件来提示写入代码页时,没有办法。
您必须使用OEM编码保存batch file。 如何做到这一点取决于你的文本编辑器。 在这种情况下使用的编码也不相同。 西方文化通常是CP850。
batch file和编码实际上是两件事情,不是特别喜欢对方。 你会注意到,Unicode也不可能在那里使用,不幸的是(尽pipe环境variables处理它很好)。
或者,您可以将控制台设置为使用其他代码页:
chcp 1252
应该做的伎俩。 至less它在我这里工作。
在执行输出redirect时,如使用dir
,则适用相同的规则。 控制台窗口的代码页被使用。 您可以使用/u
切换到cmd.exe
来强制Unicode输出redirect,从而导致生成的文件为UTF-16。
至于一般的cmd.exe
中的编码和代码页,也请看这个问题:
- cmd.exe使用什么编码/代码页
编辑:至于你的编辑:不, cmd
总是假定batch file写入控制台的默认代码页。 但是,您可以在批处理开始时轻松地包含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
我创build了下面的块,我把它放在我的batch file的开头:
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
我遇到了麻烦,这是我find的解决scheme。 在您当前的代码页中查找您正在查找的字符的十进制数字。
例如,我在代码页437( chcp
告诉你),我想要一个度数标志。 http://en.wikipedia.org/wiki/Code_page_437告诉我,度号是248。;
然后你可以find具有相同编号的Unicode字符。
248(U + 00F8)的Unicode字符是。
如果在批处理脚本中插入Unicode字符,它将显示在控制台上作为您所需的字符。
所以我的batch file
echo
版画
°
我在R中的代码(例如:±,ę,,,etc.等)中有波兰语的标志,并且在运行这个R脚本时带有.bat文件 (在输出文件中.Rout而不是那些标志%,&,#等,代码没有运行到最后)。
我的解决scheme
- 使用编码保存R脚本:文件>使用编码保存> CP1250
- 运行.bat文件
它为我工作,但如果仍有问题,请尝试使用其他编码。
我关心三个概念:
-
输出控制台编码
-
命令行内部编码(用chcp改变)
-
.bat文本编码
对我来说最简单的情况是:我会用相同的编码(比如说CP850)提到前两个,我将用同样的编码存储我的.bat(在Notepad ++中,菜单编码 → 字符集 → 西欧 → OEM 850 )。
但假设有人用另一种编码方式给我一个.bat,比如CP1252(在Notepad ++中,菜单编码*→ 字符集 → 西欧 → Windows-1252 )
然后我会改变命令行内部编码,用chcp 1252。
这改变了它用来与其他进程交谈的编码,不pipe是input设备还是输出控制台。
所以我的命令行实例将通过它的STDOUT文件描述符在1252中有效地发送字符,但是当控制台将它们解码为850(éisÚ)时会出现采样文本。
然后我修改文件如下:
@echo off perl -e "use Encode qw/encode decode/;" -e "print encode('cp850', decode('cp1252', \"ren -hlice hlice\n\"));" ren -hlice hlice
首先我打开回声,这样命令不输出,除非明确地做echo或perl -e“print …”
然后我每次需要输出一些东西的时候都会放这个样板
perl -e“use Encode qw / encode decode /;” -e“print encode('cp850',decode('cp1252',\”ren-hélicehélice\ n“));”
我用这个实际的文字来代替:ren-hélicehélice。
而且我可能需要replace我的控制台编码为cp850和其他编码为cp1252。
在下面,我把所需的命令。
我确实把问题线路打破了输出的一半,真正的命令一半。
-
第一个我肯定的:“é”通过转码被解释为“é”。 由于控制台和文件处于不同的编码,因此所有输出句子都是必需的。
-
第二,真正的命令(用@echoclosures),知道我们有相同的chcp和.bat文本的编码足以确保正确的字符解释。