[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

扩展ASCII码字符集0x00~0xff 批处理获取函数

问题描述:
特殊字符有其特殊用途,像制表符,退格符,响铃,回车,换行,文件结束符;
但其赋值需要特殊方法;另外,在坛友跟帖,贴出代码时又有不少字符被论坛直接过滤
比如:制表符(0x09),回车符(0x0d),换行符(0x0a),vt符(0x0b),ff符(0c),欧元符(0x80),还有那个和unicode文件头有关的0xff字符,另外文件结束符(0x1a)不能直接在bat源代码中赋值,要用特殊方法;
这些问题批处理自身会如何解决?
----------------------------------------------------------------------------
原帖给出了字符集获取的背景和思路;因为叙述比较繁琐,考虑到大家阅读方便,现在打包;看重思路的坛友可在此下载原帖备份文件;

这里直接给出问题的解决方案:
  1. @echo off||code by plp&title ascii 0x01~0xff 对照表
  2. setlocal enabledelayedexpansion
  3. 2>nul call ascmap /437  $ ||call:getasc $
  4. echo.
  5. set p=&set lf=!$:~0x0A,1!
  6. set hx=0 1 2 3 4 5 6 7 8 9 A B C D E F
  7. for %%a in (%hx%)do for %%b in (%hx%)do set "$%%a%%b=!$:~0x%%a%%b,1!!$:~9,1!"
  8. for %%a in (
  9. "00=<NUL>" "07=<BEL>" "08=<BS>" "09=<TAB>" "0A=<LF>" "0D=<CR>" "20=<SP>"
  10. )do set "$%%~a!$:~9,1!"
  11. for %%a in (a b c d)do set "p=!p!^!d%%a^! 0x%%%%a%%z ^!$%%%%a%%z^!!$B3:~,1! "
  12. for /f "tokens=1-4" %%a in ("0 2 4 6!lf!1 3 5 7!lf!8 A C E!lf!9 B D F")do (
  13.     (if %%a==8 echo.)&for %%z in (%hx%)do (
  14.         set/a da=0x%%a%%z,db=0x%%b%%z,dc=0x%%c%%z,dd=0x%%d%%z
  15.         for %%a in (a b c d)do set d%%a=  !d%%a!&set d%%a=!d%%a:~-3!
  16.         echo  %p:~0,-2%
  17.     )
  18. )
  19. if "%~0"=="%~f0" set/p=
  20. goto:eof
  21. :getasc <$|#|@|_|{|}|[|]> // 将0x01~0xff255个字符存放在%1变量内
  22. chcp 936>nul
  23. set %1gbk=币市布弄清分标圈唉上下同名后小成民怒易笔耕化吗战则刚猛夜思舞鸟简闹出读导能图绿
  24. chcp 437>nul
  25. Set %1=&cmd /u/c echo !%1gbk!>%tmp%\%1gbk.tmp&set/p %1gbk=<%tmp%\%1gbk.tmp
  26. for /l %%a in (0,2,76)do Set %1=!%1!!%1gbk:~%%a,1!
  27. set %1= !%1:~,31! ^^!"#$%%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^^_`abcdefghijklmnopqrstuvwxyz{|}~!%1:~-8,1!亗儎厗噲墛媽崕彁憭摂晼棙櫄洔潪煚、¥ウЖ┆辈炒刀犯购患骄坷谅媚牌侨墒颂臀闲岩釉罩棕仝圮蒉哙徕沅彐玷殛腱眍镳耱篝貊鼬!%1:~-7!
复制代码


然后是0x00字符的获取:
  1. :: 获取ascii 0x00 字符
  2. cmd /u/cecho.>$.tmp
  3. findstr/vrc:$ $.tmp>0x00.txt
复制代码


上面两个代码,说明批处理内部命令+chcp+findstr(这两个外部命令基本保险)实现了所有ascii字符的处理和存储;
这为批处理内部命令对字符的处理大大拓宽道路,使得批处理更“独立”,也使娱乐批处理更上一层楼
为了减少临时文件的生产和减少外部命令chcp,findstr的使用,从而提升代码执行效率,
本贴为此特定制了ascmap函数:
下载ascmap.cmd(ver 1.01.02):
1.2版本更新说明:兼容 在未开启变量延迟的情形下对ascmap.cmd的调用

下载ascmap.cmd(ver 1.2):

游客身份不能下载的,使用下面代码双击生成精简版 ascmap.cmd:
  1. @echo off||生产ascmap.cmd 1.2
  2. setlocal enabledelayedexpansion&chcp 936>nul
  3. :: 生产首行ascii表
  4. set gbk=币市布弄清分标圈唉上下同名后小成民怒易笔耕化吗战则刚猛夜思舞鸟简闹出读导能图绿
  5. chcp 437>nul&cmd /u/c echo !gbk!>gbk.tmp
  6. set/p gbk=<gbk.tmp
  7. if exist ascmap.cmd del/f/a ascmap.cmd
  8. Set s=&for /l %%a in (0,2,76)do Set s=!s!!gbk:~%%a,1!
  9. set $= !s:~,31! ^^!"#$%%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^^_`abcdefghijklmnopqrstuvwxyz{|}~!s:~-8,1!亗儎厗噲墛媽崕彁憭摂晼棙櫄洔潪煚、¥ウЖ┆辈炒刀犯购患骄坷谅媚牌侨墒颂臀闲岩釉罩棕仝圮蒉哙徕沅彐玷殛腱眍镳耱篝貊鼬!s:~-7!
  10. echo :!$:~1,9!^^^^!$:~10,16!^^^^!$:~26,1!!$:~27!>ascmap.cmd
  11. for /f "delims=:" %%a in ('findstr/nb :@: %~s0')do more +%%a<%~s0>>ascmap.cmd
  12. :: 添加NUL字符到文件尾部
  13. cmd/u/cecho.>gbk.tmp
  14. findstr/vrc:$ gbk.tmp>$00.tmp
  15. copy/b ascmap.cmd+$00.tmp ascmap.cmd>nul
  16. attrib +R ascmap.cmd
  17. ECHO File ascmap.cmd is created.
  18. del gbk.tmp $00.tmp
  19. if "%~0"=="%~f0" pause
  20. :@:
  21. :: get ascmap; version 1.2 ; code by plp
  22. :: 请在 http://www.bathome.net/viewthread.php?tid=12347 下载完整版本获取帮助信息
  23. @for /f "delims=/" %%a in ("%~1")do @if /%%a.==%1. chcp %%a>nul&&shift/1||exit/b 1
  24. @if %1. neq . (
  25.    set/p %1=<"%~f0"
  26.    if !!.==. (set %1= !%1:~1,9!!%1:~11,16!!%1:~28!) ELSE (
  27.       setlocal enabledelayedexpansion&set tab=!%1:~9,1!
  28.       for /f "tokens=1-3" %%a in ("!%1:~1,8!!%1:~12,15!!%1:~28!")do @(
  29.          endlocal&set %1= %%a!%tab%^
  30. %%b %%c
  31.       )
  32.    )
  33. )
  34. @if %2. neq . findstr/vrc:$ "%~f0" >"%~2"
复制代码


在此将研究该问题得到的副产品罗列如下,
不同代码页下字符个数的不同:
  1. :: 依此原理可以:
  2. :: 判断一个gbk编码下的字符串含有宽字符的个数
  3. :: 求计算字符串的字节数(没有临时文件实用)
  4. @ECHO off&chcp 437>nul
  5. Set c12=你好
  6. setlocal EnableDelayedExpansion
  7. for /l %%a in (0 1 3)do Set #%%a=!c12:~%%a,1!
  8. ECHO !c12! -^> !#0!!#3!!#2!!#1!>$.txt
  9. start notepad $.txt
复制代码

常用特殊字符的较简洁内部命令通用获取方法:
  1. :: 获取文件结束符0x1A
  2. copy nul+nul sub.txt
  3. :: 获取“退格符”, 变量b_b的值为:退格符空格退格符(0x08 0x20 0x08)
  4. for /F %%a in ('"prompt $h&for %%b in (1) do rem"')do Set b_b=%%a
  5. :: 脚本中获取回车符 0x0d
  6. for /f %%a in ('copy/z %~s0 nul')do set $0d=%%a
  7. :: 脚本中获取换行符 0x0a, ^字符后空两行;
  8. set $0a=^
  9. ::脚本中获取换页符 0x0c,
  10. for /f %%a in ('cls')do set $0c=%%a
  11. :: 936(中文)代码页下 cmd/u法获取制表符 0x09 (0x01~0x1F皆可用此法获取)
  12. for /f "delims=U" %%a in ('cmd/u/cecho 唉')do set $09=%%a
  13. :: cmd/u法获取unicode文件头0xfffe(0x80后的字符要切换代码页)
  14. chcp 936
  15. Set gbk=绿图
  16. chcp 437
  17. for /f "tokens=1-2delims=~V" %%a in ('cmd/u/cecho %gbk%')do set Un=%%a%%b
  18. :: 代码页切换法获取制表符
  19. chcp 936
  20. set $07=〇
  21. chcp 437
  22. set $07 >tab.txt
复制代码

XP 5.1.2600下"快速"获取01~1f的截取低位字节法
总共31个汉字,依次对应31个特殊字符 (注意,此法win7 失效):
  1. :: 响铃符0x07 --> 标
  2. :: 退格符0x08 --> 圈
  3. :: 制表符0x09 --> 唉
  4. :: 换行符0x0a --> 上
  5. :: 回车符0x0d --> 名
  6. :: 比如单行获取换行符:for %%a in (上:)do set $=%%~da&set $0a=!$:~,1!
  7. @echo off&setlocal enabledelayedexpansion
  8. for %%a in (
  9. 币 市 布, 弄 清 分 标 圈
  10. 唉, 上 下 同 名, 后 小 成
  11. 民 怒, 易 笔 耕 化 吗
  12. 战 则 刚 猛,夜 思 舞 鸟
  13. )do set/a n+=1&for %%b in (%%a:)do echo %%a -!n!- %%~db
  14. pause
复制代码
这里要说的是这个代码页切换法的获取制表符的原理,
大多低位特殊字符对应的宽字符还未找到:(该问题待续。。)
  1. @ECHO OFF
  2. TITLE 代码页切换法获取0X00~0X1F之间的控制字符(未完)
  3. CHCP 936
  4. Set $00=NUL{}
  5. Set $01=SOH{}
  6. Set $02=STX{}
  7. Set $03=ETX{}
  8. Set $04=EOT{}
  9. Set $05=ENQ{}
  10. Set $06=ACK{}
  11. Set $07=BEL{}
  12. Set $08=BS{}
  13. Set $09=TAB{〇}
  14. Set $0a=LF{}
  15. Set $0b=VT{♂}
  16. Set $0c=FF{♀}
  17. Set $0d=CR{}
  18. Set $0e=SO{}
  19. Set $0f=SI{¤}
  20. Set $10=dle{}
  21. Set $11=DC1{}
  22. Set $12=DC2{}
  23. Set $13=DC3{}
  24. Set $14=DC4{}
  25. Set $15=NAK{§}
  26. Set $16=SYN{}
  27. Set $17=ETB{}
  28. Set $18=CAN{↑}
  29. Set $19=EM{↓}
  30. Set $1A=SUB{→}
  31. Set $1B=ESC{←}
  32. Set $1C=FS{∟}
  33. Set $1D=GS{}
  34. Set $1E=RS{▲}
  35. Set $1F=US{▼}
  36. CHCP 437
  37. Set $
  38. set $>$.txt
  39. start $.txt
  40. Pause
复制代码


一些应用:
http://www.bathome.net/thread-12314-1-1.html
http://www.bathome.net/thread-12349-1-1.html
http://www.bathome.net/thread-12762-1-2.html
0x00字符获取思路参考:http://www.bathome.net/thread-12284-2-1.html

Thanks to:  寒夜孤星 CRLF  zqz   batman neorobin qzwqzw 。。。
附件: 您需要登录才可以下载或查看附件。没有帐号?注册
5

评分人数

回复 15# amwfjhh


    建议把大附件放到网盘上面
我帮忙写的代码不需要付钱。如果一定要给,请在微信群或QQ群发给大家吧。
【微信公众号、微信群、QQ群】http://bbs.bathome.net/thread-3473-1-1.html
【支持批处理之家,加入VIP会员!】http://bbs.bathome.net/thread-67716-1-1.html

TOP

这是一个论坛的漏洞,欧元符号()被忽略了
附件: 您需要登录才可以下载或查看附件。没有帐号?注册

TOP

TOP

TOP

奇思妙想……
晓得拆字方法后可以自己遍历一下需要代码的相关宽字符,再挑一个可以手输的用来作变量截取,再通过代码页车换将宽字符拆成高低字符,这样貌似都不需要cmd /u了,直接chcp就可以实现,只是需要去寻找这些特殊字符,先测试一下看看。


PS:
测试结果,遍历了下0~255*255内的本地化字符,单纯用本地化的DBCS(双字符字集),要取到没有歧义的字符,高位字节必大于0x80,且低字节大于等于0x40即0x814*以上才有不被之前字符重复的有效双字节字符,这即意味着要从双字节里面取需要的值,不管是低字节还是高字节,都有取不到的区间,还是用unicode可行。
有兴趣的同学可以参考下附件的表格。

链接: https://pan.baidu.com/s/1ouycfG6Q5V8u2FVVeayqlg 提取码: iaus
附件: 您需要登录才可以下载或查看附件。没有帐号?注册

TOP

重定向到文件时才是0x00~0xFF,在内存中有部分不属于0x00~0xFF。

TOP

回复 13# playinthesky


    我也是 win7 系统,可以正常运行呀...以下为半角转全角代码,试试正常不:
  1. @echo off&setlocal enabledelayedexpansion
  2. chcp 437
  3. call ascmap $
  4. (for /l %%a in (32 1 126) do (
  5. set /a "n=%%a+128"
  6. for /f "eol= delims=" %%b in ("!n!") do (
  7. echo [!$:~%%a,1!=!$:~163,1!!$:~%%b,1!]
  8. )
  9. ))>全角字符.txt
  10. pause
复制代码

TOP

12# plp626
WINDOWS 7下貌似不能调用。

TOP

11# guo135956


你的,详细环境和测试代码是?

TOP

无效代码页
系统找不到指定的文件。
eof=→
626
〇#
请按任意键继续. . .

TOP

看到plp兄的拆分法之前曾寄希望于cmd /u,但是测试后发现不行,内容全变了,除此以外啥想法都没有...

TOP

8# batman


可是“在中文代码页下”应该用不了拆分法吧...很纳闷,等待正解

TOP

plp626终于又回到拆分法上来了,呵呵。。。
***共同提高***

TOP

plp_00=刀 阀 怀 开 攀 退 稀 销 需 言 耀 一 匀 最
plp_01=币 持 愁 丁 封 搁 阁 洁 老 码 企 省 谁 送 锁 态 威
plp_02=昂 蜂 挂 搂 茂 漂 适 市 堂 异 脂
plp_03=布 吃 调 范 考 七 弃 球 刃 逃 娃
plp_04=锄 ...
plp626 发表于 2011-5-19 17:17

原来那个帖子的素材是从这里捣鼓过去的...

TOP

返回列表