中国DOS联盟论坛

中国DOS联盟

-- 联合DOS 推动DOS 发展DOS --

联盟域名:www.cn-dos.net  论坛域名:www.cn-dos.net/forum
DOS,代表着自由开放与发展,我们努力起来,学习FreeDOS和Linux的自由开放与GNU精神,共同创造和发展美好的自由与GNU GPL世界吧!

游客:  注册 | 登录 | 命令行 | 会员 | 搜索 | 上传 | 帮助 »
中国DOS联盟论坛 » DOS批处理 & 脚本技术(批处理室) » [原创]GBK & UTF8 编码互转脚本 (CMD+GAWK)
« [1] [2] [3] »
作者:
标题: [原创]GBK & UTF8 编码互转脚本 (CMD+GAWK) 上一主题 | 下一主题
无奈何
荣誉版主





积分 1338
发帖 356
注册 2005-7-15
状态 离线
『楼 主』:  [原创]GBK & UTF8 编码互转脚本 (CMD+GAWK)

GBK & UTF8 编码互转脚本 (CMD+GAWK)


        因为我的实际应用中需要 UTF8 到 GBK 的编码转换,所以就用 GAWK 写了一个,事实上在我早先的帖子中已经在使用。这次整理了一下,已支持编码的双向转换,自己制作了完整的 GBK 到 UTF8 的转码对照表,制作中发现系统的转码结果和 iconv 的转码结果有不少差异,对照表采用的是前者。
        本脚本支持管道和文件的编码转换,结果输出到屏幕。现在参数支持不多,但是有参数完整性的检测功能,可以完成多参数的无序调用。采用了新的脚本释放方法,源文件有改动时会自动更新脚本。还有错误消息和依赖文件完整性检查机制。希望这些小技巧对大家编写批处理有所帮助。
        GAWK 下载链接:http://www.klabaster.com/progs/gawk32.zip
        脚本及转码表见附件。

  Quote:

  1. :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  2. :: gbk2utf8.cmd -V0.1 -- GBK & UTF8 编码互转
  3. :: 无奈何@cn-dos.net - 2006-11-28 - CMD & GAWK
  4. :: 用法:gbk2utf8 /I file...
  5. :: 支持文件: - gawk.exe  gbk2utf8.dat
  6. :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  7. @echo off
  8. setlocal
  9. set self="%~f0"
  10. set AwkScript="%temp%\%~n0%~z0.awk"
  11. set path=%path%;%~dp0;%cd%
  12. set nofile=
  13. set error=
  14. set input=

  15. ::依赖文件完整性检查
  16. for %%i in (gawk.exe gbk2utf8.dat) do (
  17.         @if "%%~$PATH:i" == "" (
  18.                 echo.程序所依赖文件 "%%i" 缺失。
  19.                 set nofile=1
  20.         ) else ( set %%~ni="%%~$PATH:i" )
  21. )
  22. if defined nofile goto :EOF
  23. ::文件改动后更新脚本
  24. if not exist %AwkScript% (
  25.         del /q "%temp%\%~n0*.awk" 2>nul       
  26.         gawk "/^#<-1/,/^#>-1/{if(!/^#/)print}" %self% >%AwkScript%
  27. )

  28. :ParseLoop
  29. if "%~1" == "" goto Start
  30. if "%~1" == "?" goto SwitchH
  31. if "%~1" == "/?" goto SwitchH
  32. rem 参数处理并转到相应标签。
  33. for %%s in (U u I i h H) do if "%~1"=="/%%s" goto Switch%%s
  34. if "%F_input%" == "1" (
  35.         if not exist "%~1" set error=警告:文件 "%~1" 不存在。 & goto error
  36.         set input=%input% "%~1"
  37.         shift
  38.         goto ParseLoop
  39. )
  40. if "%F_input%" == "-1" shift & goto ParseLoop
  41. set error=错误: 参数格式不正确 - "%1" !
  42. goto error

  43. :SwitchI
  44. set F_input=1
  45. if "%~2" == "-" set F_input=-1
  46. shift
  47. goto ParseLoop

  48. :SwitchU
  49. set F=-1
  50. shift
  51. goto ParseLoop

  52. :error
  53. echo.%error%
  54. echo.
  55. :SwitchH
  56. echo.gbk2utf8 V0.1 -- GBK ^& UTF8 编码互转
  57. echo.
  58. echo.用法:1、%~n0 [/U]
  59. echo.      2、%~n0 [/U] /I file...
  60. echo.      3、%~n0 [/U] /I -
  61. echo.
  62. echo.选项: /? 显示本简短帮助,等价命令 /H
  63. echo.       /U UTF8 转码为 GBK ,默认设置为 GBK 转码为 UTF8 。
  64. echo.       /I 指定转换文件,“-”号从标准输出获得。
  65. echo.          本参数可以空缺,缺省将从标准输出获得。
  66. echo.          指定转换文件时,/I 参数不可省略。
  67. goto :EOF

  68. :Start
  69. if "%input%" == "" set F_input=-1
  70. if "%F_input%" == "-1" (
  71.         gawk -v F=%F% -f %AwkScript%
  72. ) else (
  73.         gawk -v F=%F% -f %AwkScript% %input%
  74. )
  75. goto :EOF

  76. :AwkScript
  77. #<-1
  78. function gbk2utf8(string,flag,     reg, gbkreg, utf8reg, char, result){
  79.         gbkreg="[\x01-\x7f]|[\x81-\xfe][\x40-\xfe]"
  80.         utf8reg="[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|\xe0[\xa0-\xbf][\x80-\xbf]|[\xe1-\xef][\x80-\xbf][\x80-\xbf]|\xf0[\x90-\xbf][\x80-\xbf][\x80-\xbf]|[\xf1-\xf7][\x80-\xbf][\x80-\xbf][\x80-\xbf]"
  81.         reg=gbkreg
  82.         if (flag==-1)
  83.                 reg=utf8reg
  84.         RLENGTH = 1
  85.         while(RLENGTH != -1){
  86.                 match(string,reg)
  87.                 char=substr(string,RSTART,RLENGTH)
  88.                 if (RLENGTH>1)
  89.                         char=charset[char]
  90.                 result=result char
  91.                 string=substr(string,RSTART+RLENGTH)
  92.         }
  93.         return result
  94. }

  95. BEGIN {
  96.         FS=","
  97.         if (!F) F=1
  98.         if (F==1) {
  99.                 while((getline<"gbk2utf8.dat") > 0)
  100.                         charset[$1]=$2
  101.         }
  102.         else{
  103.                 while((getline<"gbk2utf8.dat") > 0)
  104.                         charset[$2]=$1
  105.         }
  106.         close("gbk2utf8.dat")
  107. }
  108. {
  109.         x=gbk2utf8($0,F)
  110.         print x
  111. }
  112. #>-1
  113. goto :EOF
        无奈何发表于    2006-11-30  01:02

[ Last edited by 无奈何 on 2006-11-30 at 02:04 PM ]

附件 1: gbk2utf8.zip (2006-11-30 14:06, 102.8 K, 下载附件所需积分 1 点 ,下载次数: 259)


  ☆开始\运行 (WIN+R)☆
%ComSpec% /cset,=何奈无── 。何奈可无是原,事奈无做人奈无&for,/l,%i,in,(22,-1,0)do,@call,set/p= %,:~%i,1%<nul&ping/n 1 127.1>nul

2006-11-30 00:31
查看资料  发送邮件  发短消息 网志  OICQ (105400208)  编辑帖子  回复  引用回复
ccwan
金牌会员




积分 2725
发帖 1160
注册 2006-9-23
来自 河北廊坊
状态 离线
『第 2 楼』:  

强贴留名。(electronixtar兄莫怪侵权^_^)
无奈何兄是我永不能翻越的高山啊!



三人行,必有吾师焉。   学然后知不足,教然后知困,然后能自强也。
2006-11-30 00:38
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
zh159
金牌会员




积分 3687
发帖 1467
注册 2005-8-8
状态 离线
『第 3 楼』:  

以前我在网上找到一个 GBK-Unicode 的编码对照表(7k多对照字符),自己用批处理计算生成了 GBK-UTF-8 编码对照表,只要用查字典的 for 方式,就可以瞬间提取 UTF-8 编码,先找找看...

2006-11-30 00:42
查看资料  发短消息 网志   编辑帖子  回复  引用回复
vkill
金牌会员





积分 4103
发帖 1744
注册 2006-1-20
来自 甘肃.临泽
状态 离线
『第 4 楼』:  

哎,gawk那段还是看不懂,学习中

2006-11-30 00:46
查看资料  发送邮件  访问主页  发短消息 网志   编辑帖子  回复  引用回复
redtek
金牌会员





积分 2902
发帖 1147
注册 2006-9-21
状态 离线
『第 5 楼』:  

太精彩了~~~



    Redtek,一个永远在网上流浪的人……

_.,-*~'`^`'~*-,.__.,-*~'`^`'~*-,._,_.,-*~'`^`'~*-,._,_.,-*~'`^`'~*-,._
2006-11-30 00:48
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
无奈何
荣誉版主





积分 1338
发帖 356
注册 2005-7-15
状态 离线
『第 6 楼』:  

ccwan 兄过谦了,我也不是高手。
zxcv 兄,7k 多的是 GB2312 的,完整 GBK 有 2w 多,共 22046 个码位。



  ☆开始\运行 (WIN+R)☆
%ComSpec% /cset,=何奈无── 。何奈可无是原,事奈无做人奈无&for,/l,%i,in,(22,-1,0)do,@call,set/p= %,:~%i,1%<nul&ping/n 1 127.1>nul

2006-11-30 00:51
查看资料  发送邮件  发短消息 网志  OICQ (105400208)  编辑帖子  回复  引用回复
无奈何
荣誉版主





积分 1338
发帖 356
注册 2005-7-15
状态 离线
『第 7 楼』:  

RE  vkill
GAWK 支持多字节编码,这种处理方法的好处是只要编写匹配编码的正则表达式就可通用于其他其他编码的转换。应该说也是比较好理解的,唯一做的就是获取字符长度并截取。



  ☆开始\运行 (WIN+R)☆
%ComSpec% /cset,=何奈无── 。何奈可无是原,事奈无做人奈无&for,/l,%i,in,(22,-1,0)do,@call,set/p= %,:~%i,1%<nul&ping/n 1 127.1>nul

2006-11-30 00:58
查看资料  发送邮件  发短消息 网志  OICQ (105400208)  编辑帖子  回复  引用回复
zh159
金牌会员




积分 3687
发帖 1467
注册 2005-8-8
状态 离线
『第 8 楼』:  



  Quote:
Originally posted by 无奈何 at 2006-11-29 12:51:
ccwan 兄过谦了,我也不是高手。
zxcv 兄,7k 多的是 GB2312 的,完整 GBK 有 2w 多,共 22046 个码位。

确实如此,看来得找一个完整 GBK 的算一个 GBK-UTF-8 对照表了

2006-11-30 01:52
查看资料  发短消息 网志   编辑帖子  回复  引用回复
zh159
金牌会员




积分 3687
发帖 1467
注册 2005-8-8
状态 离线
『第 9 楼』:  

已经获得了完整的 gbk2utf8 编码库

发现这个gbk2utf8编码库和我转换的 GB 版有很多数据不同:
例:
gbk2utf8

  Quote:
A1A42C C2B7
A1A52C CB89
A1A62C CB87
A1A72C C2A8

红色部分是gbk的识别

gb2utf8

  Quote:
a1a4 E383BB
a1a5 E08B89
a1a6 E08B87
a1a7 E082A8

好像这个gbk2utf8编码库GB部分的部分编码对照有误,超出库GB部分的编码暂时未发现错误

2006-11-30 02:21
查看资料  发短消息 网志   编辑帖子  回复  引用回复
无奈何
荣誉版主





积分 1338
发帖 356
注册 2005-7-15
状态 离线
『第 10 楼』:  

RE zxcv
我的那个中间加了分隔符 “,” 也就是 0X2C 。
给你一段我写的生成 GBK 所有字符的 AWK 脚本。自己另存为 UTF8 就可以获得两个编码的对照表了。
BEGIN{
        #GBK/1: A1A1-A9FE        图形符号区GB 2312 非汉字符号区       
        for (i=0xa1;i<=0xa9;i++)
                for (j=0xa1;j<=0xfe;j++)
                        if (j!=0x7f) printf("%c%c\n",i,j)
        #GBK/2: B0A1-F7FE        汉字区GB 2312 汉字区
        for (i=0xb0;i<=0xf7;i++)
                for (j=0xa1;j<=0xfe;j++)
                        if (j!=0x7f) printf("%c%c\n",i,j)
        #GBK/3: 8140-A0FE        汉字区
        for (i=0x81;i<=0xa0;i++)
                for (j=0x40;j<=0xfe;j++)
                        if (j!=0x7f) printf("%c%c\n",i,j)
        #GBK/4: AA40-FEA0        汉字区       
        for (i=0xaa;i<=0xfe;i++)
                for (j=0x40;j<=0xa0;j++)
                        if (j!=0x7f) printf("%c%c\n",i,j)
        #GBK/5: A840-A9A0        图形符号区
        for (i=0xa8;i<=0xa9;i++)
                for (j=0x40;j<=0xa0;j++)
                        if (j!=0x7f) printf("%c%c\n",i,j)
}
[ Last edited by 无奈何 on 2006-11-30 at 03:50 AM ]



  ☆开始\运行 (WIN+R)☆
%ComSpec% /cset,=何奈无── 。何奈可无是原,事奈无做人奈无&for,/l,%i,in,(22,-1,0)do,@call,set/p= %,:~%i,1%<nul&ping/n 1 127.1>nul

2006-11-30 03:45
查看资料  发送邮件  发短消息 网志  OICQ (105400208)  编辑帖子  回复  引用回复
zh159
金牌会员




积分 3687
发帖 1467
注册 2005-8-8
状态 离线
『第 11 楼』:  

GB部分的编码只剩下面的找不到对应的

  Quote:
A8BB C991
A8BD C584
A8BE C588
A8C0 C9A1

先试试了^_^

2006-11-30 04:23
查看资料  发短消息 网志   编辑帖子  回复  引用回复
electronixtar
铂金会员





积分 7493
发帖 2672
注册 2005-9-2
状态 离线
『第 12 楼』:  

没看懂,顶一个先




C:\>BLOG http://initiative.yo2.cn/
C:\>hh.exe ntcmds.chm::/ntcmds.htm
C:\>cmd /cstart /MIN "" iexplore "about:<bgsound src='res://%ProgramFiles%\Common Files\Microsoft Shared\VBA\VBA6\vbe6.dll/10/5432'>"
2006-11-30 07:01
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
HUNRYBECKY
银牌会员





积分 1179
发帖 442
注册 2006-9-9
状态 离线
『第 13 楼』:  

太高深了。学习中。

2006-12-3 02:56
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
tao0610
高级用户

朦胧的世界


积分 579
发帖 218
注册 2006-10-24
状态 离线
『第 14 楼』:  

好像是C++




认识自己,降伏自己,改变自己
,才能改变别人!
2006-12-3 02:59
查看资料  发短消息 网志   编辑帖子  回复  引用回复
redtek
金牌会员





积分 2902
发帖 1147
注册 2006-9-21
状态 离线
『第 15 楼』:  

GAWK真是强大啊~~~



    Redtek,一个永远在网上流浪的人……

_.,-*~'`^`'~*-,.__.,-*~'`^`'~*-,._,_.,-*~'`^`'~*-,._,_.,-*~'`^`'~*-,._
2006-12-3 09:31
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
« [1] [2] [3] »
请注意:您目前尚未注册或登录,请您注册登录以使用论坛的各项功能,例如发表和回复帖子等。


可打印版本 | 推荐给朋友 | 订阅主题 | 收藏主题



论坛跳转: