Board logo

标题: [文本处理] [分享]批处理用chcp 65001处理Unicode字符 [打印本页]

作者: Demon    时间: 2011-6-13 15:57     标题: [分享]批处理用chcp 65001处理Unicode字符

问题出自《批处理有什么办法处理unicode字符?》一帖,摘录如下:
批处理有办法处理unicode字符吗? 例如: "☀☁☂☃☭☄☢" 的这些字符
如果我要用批处理建这样的一个文件夹:
  1. md .\文件夹☁
复制代码
复制代码直接这样批处理是不会运行,有办法解决吗?


qzwqzw的回复
问题似乎无解
批处理必须以ANSI编码保存
否则cmd无法正常处理
而中文locale下的ANSI对应的GBK字符集
是没有楼主所提到的那些字符的

然后楼主就结帖了。

真的无法实现吗?对于权威我们要敢于怀疑,在无数次Google无数次链接被重置之后,我似乎找到了答案。

“批处理必须以ANSI编码保存,否则cmd无法正常处理”,真的是这样吗?把下面代码保存为utf-8.bat,保存时选择UTF-8编码
  1. @echo 你好
复制代码
注:不要使用记事本保存,因为记事本保存UTF-8编码时会自动在文件前加上BOM(Byte Order Mark),即十六进制的EFBBBF,影响批处理的解析。推荐使用EditPlus,下载地址:http://www.editplus.com/download.html,注册码在线生成:http://demon.tw/my-work/editplus-regcode-online.html

打开命令提示行,切换到utf-8.bat所在目录,运行之,输出:
  1. C:\Users\Demon\Desktop>utf-8.bat
  2. 浣犲ソ
复制代码
输出乱码而不是预期的“你好”,为什么会这样呢?因为“中文locale下的ANSI对应的GBK字符集”,即代码页936。cmd.exe在解析批处理命令时是按照默认代码页的编码来解析的。众所周知,所有的文件都是以二进制的形式保存的,但是同样的二进制序列用不同的编码来解析得到的结果是不一样的,例如:
  1. E4 BD A0 E5 A5 BD
复制代码
如果以UTF-8编码来解析是“你好”,而用GBK来解析是“浣犲ソ”,即上面输出的结果。

于是想到了用chcp来切换代码页,65001代码页对应的是UTF-8编码,于是输入:
  1. C:\Users\Demon\Desktop>chcp 65001
  2. Active code page: 65001
  3. C:\Users\Demon\Desktop>utf-8.bat
  4. The system cannot write to the specified device.
复制代码
结果却令人失望,也并不是预期的“你好”,Google了半天,传说是raster font(点阵字体)搞的鬼,于是右键单击命令提示行的标题栏,选择属性,将字体改成Lucida Console,确定,再次输入:
  1. C:\Users\Demon\Desktop>utf-8.bat
  2. 你好
复制代码
得到了我们想要的输出,因为经过刚才的修改,cmd.exe已经将默认代码页改成65001了(注:但是右键属性中仍然显示936),解析批处理文件的时候使用的也是用UTF-8,所以能正确输出。于是下面代码也能正常运行(保存为UTF-8编码):
  1. md .\文件夹☁
复制代码
但是这样并没有可移植性性,因为需要手动修改cmd.exe的设置,幸运的是,cmd.exe的设置是保存在注册表的,在Windows 7系统(其他系统可能会不一样)可以通过导入下面.reg文件进行设置:
  1. Windows Registry Editor Version 5.00
  2. [HKEY_CURRENT_USER\Console\%SystemRoot%_system32_cmd.exe]
  3. "CodePage"=dword:0000fde9
  4. "WindowSize"=dword:00180050
  5. "FontSize"=dword:000c0000
  6. "FontFamily"=dword:00000036
  7. "FontWeight"=dword:00000190
  8. "FaceName"="Lucida Console"
复制代码
以上代码在Windows 7 Ultimate 英文版下通过测试,欢迎各位高手指点和补充。

参考链接(排名不分先后):
1、http://blogs.msdn.com/b/michkap/archive/2008/03/18/8306597.aspx
2、http://stackoverflow.com/questio ... -if-chcp-was-called
3、http://stackoverflow.com/questio ... irection-on-cmd-exe
作者: Hello123World    时间: 2011-6-13 16:23

我本来想加10分的,提示超过限制?
作者: CrLf    时间: 2011-6-13 17:00

本帖最后由 zm900612 于 2011-6-13 17:04 编辑

漂亮!
utf-8中只有宽字符是不同于ansi的,所以此处的英文字符能被cmd识别为命令,而以utf-8存储的特殊字符在65001代码页下又能被正确读取,这个思路真是巧妙,太棒了。
作者: neorobin    时间: 2011-6-13 18:12

对楼主的研究有兴趣
再仔细看, 喜欢这个网站 stackoverflow.com
作者: applba    时间: 2011-6-13 18:51

字符、字符集……
ansi、unicode……
编码、内码、代码页……
ascii、gbk、utf-8、unicodebig……
作者: qzwqzw    时间: 2011-6-14 21:16

楼主钻研的精神值得赞赏
只是权威什么就有些严重了
都是长河中的一朵浪花而已

不知道楼主在XP下测试过没有?
我的测试结果是失败的
在chcp和更换字体之后
执行utf-8.cmd未看到任何输出
此时type utf-8.cmd倒是可以看到 “echo 你好”的内容
在chcp 437下可以看到echo Σ╜áσÑ╜的文字
距离成功也许仍有一步之遥
作者: plp626    时间: 2011-6-14 22:28

思维火花:

用纯批处理做编码互转(无需查表),有时间搞一个和大家分享下。。
作者: plp626    时间: 2011-6-14 23:13

6# qzwqzw

我这里和你的一样,xp下:
代码页切换到65001后,bat源文件被当做utf-8的编码解析,但cmd好像并不认识,直接无视。

win7没用过。
作者: yue    时间: 2011-6-15 09:57

各位研究好像已经偏离了我的要求;我的目的是要让bat程序可以建立像"文件夹☁"这样含有unicode字符的文件夹,如果要修改注册表达到目的的话,觉得有"杀鸡取卵"的感觉;还有就是我提到的☀☁☂☃☭☄☢字符和各位程序显示出来的乱码是有区别的;我的字符可以防止"冰刃"读取文件夹的内容,而各位的不能!!
作者: CrLf    时间: 2011-6-15 14:29

9# yue

很不客气地说,你根本没耐心看完顶楼的一半内容,别人花大力气帮你解决问题,牵涉到一些你看不懂的的技术探讨也是从“无偿帮助”中引申出来的,而你说的话让我感觉,好像为你解决问题是理所当然,除此之外不允许有任何想法。
作者: yue    时间: 2011-6-15 14:47

10# zm900612 可能我话有点直接,但也只是一针见血地说出我的想法,同样也是研究探讨,如果不说清楚研究方向目标,那研究又有何意义呢? 没有什么其他意思.
作者: CrLf    时间: 2011-6-15 14:54

11# yue

可知道我为什么说你连顶楼的一半内容都耐心没看完吗?因为楼主在顶楼已经给出解答了,虽然不适用于xp,但是只要把这个帖子从头到尾看完,就不会说出“各位研究好像已经偏离了我的要求”这句话
作者: yue    时间: 2011-6-15 15:59

12# zm900612 我可以明确的说我是全部仔细看完楼主的内容的,也尝试了楼主的代码,而且是在win7下; 以上代码在Windows 7 Ultimate 中文版下测试是不行的.
如果说我否认了指出了各位研究成果的错误,而使大家不快的话,那就当我是放屁;我不会再说话了,那你们继续继续...
作者: CrLf    时间: 2011-6-15 17:51

13# yue

同样的系统,为什么我测试后证明可行(见附件)?
你觉得我们已经偏离了你的问题是吗,可是我们在这个帖子里讨论的东西一旦找到解决的方法,你的问题自然迎刃而解。
这世上没有无所不知的圣人,面对许多第一次碰到的问题,一个人可能难以解决,这时候就需要大家一起讨论,互相拓展和校正思路,如果这就是所谓的“不实用”,或者用你的观点来看,帮不上你就叫不实用,那我真觉得没必要无偿帮助你了,因为也许你以后也会以“不实用”为借口拒绝帮助他人。
那天一看到你的帖子,虽然没有这种处理特殊字符的经验,但是仍然花了大量的时间做猜想、做实验,只是始终无法解决根本性的问题,所以无法给出有效解答,相信别的回帖者也都是如此,别人为了帮你而在背后花费了大量的精力,甚至可能远远超过提问者,又凭什么遭到否定?
作者: Hello123World    时间: 2011-6-15 21:18

13# yue
可以防止"冰刃"读取文件夹的内容

真的假的——这点值得试试哦,可以放些“被和谐”软件。(防不防360之类杀毒软件?)
作者: Hello123World    时间: 2011-6-15 21:20

小红伞可以扫描,不知道其它杀软怎样。
作者: wankoilz    时间: 2011-6-16 09:38

前两天我因GBK特殊字符太少而郁闷,这就看到Bat兼容Unicode了,真是太好了!
作者: applba    时间: 2011-6-16 17:52

本帖最后由 applba 于 2011-6-16 17:53 编辑

经测试,xp下cmd.exe能读无bom的utf-8文本文件,但是只要有特殊字符就拒绝执行……
作者: qzwqzw    时间: 2011-6-16 20:20

楼上是如何测试的呢?

我这里的结果是
cmd下不改变代码集到65001
总是可以正常执行并输出乱码的

一旦改变代码集到65001
执行任何批处理都无反应
包括ANSI编码的批处理
作者: Tuberose    时间: 2011-7-3 18:24

楼上是如何测试的呢?
作者: 极品小猫    时间: 2015-12-14 15:34

又来挖坟了。改了之后,Bat也必须是 Unicode 编码
用完了还得改回来,还是比较麻烦
作者: tjs82761    时间: 2019-5-27 10:59

留个记录再来学习




欢迎光临 批处理之家 (http://www.bathome.net/) Powered by Discuz! 7.2