Board logo

标题: [文件操作] [已解决]DAT文件中有ASCII码分隔,批处理是否能调用ASCII码当作分隔符? [打印本页]

作者: playinthesky    时间: 2011-8-23 22:24     标题: [已解决]DAT文件中有ASCII码分隔,批处理是否能调用ASCII码当作分隔符?

  1. @echo off&setlocal enabledelayedexpansion
  2. call ascmap $
  3. for %%a in (123.dat) do (
  4.   for /f "delims=" %%b in (%%a) do (
  5.     set "pind=!$:~0x05,1!"
  6.     set "pind=;"
  7.     set "str=%%b"
  8.     set "str=!str:;= !"
  9.       for %%i in (!str!) do (
  10.         for %%j in (!str!) do (
  11.           if "%%i" equ "%%j" set /a n+=1
  12.         )
  13.         if !n! gtr 3 del %%a 2>nul
  14.         set n=
  15.       )
  16.    )
  17. )
  18. pause
复制代码
拜读了论坛高手的文章,想实现效果
在dat文件中
都由 草花符号 作为数据的分隔,查询了 ASCII 码例,是 0x05, 是否可以比对分隔符中的内容,发现重复超过3次删除该dat文件。

例子:A.dat (以下草花为符号,不是汉字。)

草花HD-4F草花ED-2F草花6D-3F草花HD-GF草花HD-4F草花HD-4F草花FD-3F草花ED-GF草花HD-4F草花


因为文件内容中有 "草花HD-4F" 3个以上,所以将DAT 文件删除。

!$:~0x05,1! 为什么最后是 ,1 是第一行的意思吗? 还有 !  ! 之间 是否能再次赋值?
  1. @echo off&setlocal enabledelayedexpansion
  2. call ascmap $
  3. for %%a in (123.dat) do (
  4.   for /f "delims=" %%b in (%%a) do (
  5.     set "str=%%b"
  6.     set "str=!str:!$:~0x05,1!= !"
  7.       for %%i in (!str!) do (
  8.         for %%j in (!str!) do (
  9.           if "%%i" equ "%%j" set /a n+=1
  10.         )
  11.         if !n! gtr 3 del %%a 2>nul
  12.         set n=
  13.       )
  14.    )
  15. )
  16. pause
复制代码
貌似也是不成功,求高手指点,谢谢了。

使用 hiew 8.1 查看了十六进制,对unicode 和 ascii 编码的区别不是很理解。

call ascmap $  已经按照"plp626" 大侠的加载成功,并在屏幕下能够打印ASCII字符,附原DAT文件

因为论坛限制上传rar文件,只能将附件改名成txt,下载下来改名成RAR,解压之后有123.dat 和 a.dat 两个文件,删除那个重复内容多的那个123.dat, a.dat 保留。
作者: CrLf    时间: 2011-8-23 22:46

大致看了下,比较可能的错误原因如下:
  1. 1、那个 ascmap 是集成函数,需要保存到 path 路径或者当前目录,请确认此函数文件是否存在
  2. 2、同级的变量相互嵌套需要借助 call 或者 for :
  3. for %%a in ("!$:~0x05,1!= ") do set "str=!str:%%~a=!"
  4. 3、将草花替换为空格的办法并不适合存在连续草花的情况,而且也需要确保文本中不存在空格、制表符等特殊字符
复制代码
思路:
  1. 1、如果两个符号之间不连续,可以通过 for /f "tokens=1-4 delims=%$:~0x5,1%" %%a in... 来以草花符号划分行内容,只要存在 %%b 或者更高的参数变量说明语句中存在草花
  2. 2、否则,可以合并所有行,并将草花替换为换行符,然后...
  3. 3、实在不行就逐字判断吧
复制代码

作者: hfg1977    时间: 2011-8-23 23:43

看级几遍LZ的表述,  没看懂.

猜测其意思是 某DAT文件,以草花符号(0x05)分割,若有3+处重复则删除该DAT文件.
首先纠正LZ的几个基础错误:
1. 草花符号(0x05), 仅仅是你在CMD字符环境下看到的.,在notepad中是个羊头,在IE中是""
   在ASCII字符表中它属于不可见字符,即控制用字符. 控制用字符在不同环境影像是不同的.
2. CMD不能直接操作16进制字符.

不建议用"控制字符"做分隔符.
  1. @echo off
  2. setlocal enabledelayedexpansion&cls
  3. :start ============================================================
  4. for /f "tokens=* usebackq delims=" %%a in ("01.txt") do (
  5. set str=%%a
  6. set str=!str:= !
  7. set str=!str:-=m!
  8. for %%A in (!str!) do (
  9. set/a _%%A+=1
  10. echo %%A 出现!_%%A!次
  11. if !_%%A! GEQ 3 (echo gtr 3 wait del is ...)
  12. ))
  13. :end ==============================================================
  14. endlocal&echo 按任意键退出&pause>nul
复制代码

作者: hfg1977    时间: 2011-8-23 23:51

代码的第4的分隔符, 第6行需替换的" " 看起来是空格,其实是羊头.

再告诉你羊头的写法:  echo  ++^E++>21.txt
再告诉你"^E" 的写法: CMD环境, "ctrl + E" 两个键同时按,或按住"ctrl" 再按"E"
作者: playinthesky    时间: 2011-8-24 10:35

本帖最后由 playinthesky 于 2011-8-24 20:20 编辑
  1. @echo off&setlocal enabledelayedexpansion
  2. call ascmap $
  3. for  %%a in (*.dat) do (
  4.   for /f "delims=%$:~0x05,1% usebackq tokens=*" %%b in (%%a) do (
  5.     set "str=%%b"
  6.     set "str=!str:%$:~0x05,1%= !"
  7.     set "str=!str:-=^!"
  8.       for %%i in (!str!) do (
  9. if defined _%%i (set /a _%%i+=1
  10.         )  else (
  11.            set /a _%%i=1
  12.         )
  13.       )
  14.       for /f "tokens=1,2 delims=_=" %%j in ('set _') do echo 出现 %%k 的次数 %%p
  15.         if %%p gtr %%k del %%a
  16.    )
  17. )
  18. pause
复制代码
计数器很难调用,就是统计出现的数目,若是出现数目超过一定数目就将其文件删除,高手,帮帮我。
作者: playinthesky    时间: 2011-8-24 16:41

回复 4# hfg1977


    谢谢你的指点,我自己在去试试看,感到很难做到分开统计。
作者: playinthesky    时间: 2011-8-24 16:43

回复 2# CrLf


    感谢您的思路,我再试试看!
作者: playinthesky    时间: 2011-8-24 18:15

回复 4# hfg1977
  1. @echo off&setlocal enabledelayedexpansion
  2. call ascmap $
  3. for %%a in (1.dat) do (
  4.   for /f "usebackq delims= tokens=* " %%b in ("%%a") do (
  5.     set "str=%%b"
  6.     set "str=!str:%$:~0x01,1%=!"
  7.     set "str=!str:%$:~0x02,1%=!"
  8.     set "str=!str:%$:~0x03,1%=!"
  9.     set "str=!str:%$:~0x1E,1%=!"
  10.     set "str=!str:%$:~0x04,1%= !"
  11.     set "str=!str:%$:~0x05,1%= !"
  12.     set "str=!str:%$:~0x2D,1%=!"
  13.       for %%i in (!str!) do (
  14.         set/a _%%i+=1
  15.         echo %%i 出现 !_%%i!次
  16.      if !_%%i! gtr 3 del %%a
  17.       )
  18.   )
  19. )
  20. pause
复制代码
但是如果用 *.dat 的话,因为计数不会按照每个dat文件统计,所以删除出现内容重复的dat 也是错误的,是否能发现每个dat文件出现重复数超过3+的时候删除,你之前理解的意思是正确的!!大哥
作者: hfg1977    时间: 2011-8-24 19:51

因为计数不会按照每个dat文件统计,所以删除出现内容重复的dat 也是错误的,是否能发现每个dat文件出现重复数超过3+的时候删除


当然可以, 每处理完一个文件把变量清空.
作者: hfg1977    时间: 2011-8-24 19:56

  1. set str=!str:-=m!
  2. for %%A in (!str!) do (
  3. set/a _%%A+=1
  4. ...
复制代码
要把 "str'中的"运算符号"替换掉, 不然for中的 "set/a"计算会出错
作者: playinthesky    时间: 2011-8-24 20:03

回复 10# hfg1977


    不会,真的不会,将计数器统计一个文件之后清空,还有就是没清空之前计算好,大于三个的文件删除如何写代码。请明示吧,谢谢你了!!
作者: playinthesky    时间: 2011-8-24 20:04

回复 10# hfg1977


    怎么清空变量?
作者: hfg1977    时间: 2011-8-24 20:07

你要处理的文件很多,且都是如上传文件类似用"草花"分隔的?
这个要问清,不然没法写code.
作者: playinthesky    时间: 2011-8-24 20:18

回复 13# hfg1977


    全部是用草花分隔的,有很多很多个文件,就是要将草花内的内容统计,遇到重复的内容统计,单个文件内出现3个一样或更多的,就将此文件删除,最后剩下的文件都是在草花间隔内的内容不相同的,或者说出现小于3的。

我就是计数器弄不好,无法让计数器在处理完一个文件之后,重新计数和删除,单个文件大致我是这样写的,但是需要判断 3+的话,将重复出现3+的文件删除。
  1. @echo off&setlocal enabledelayedexpansion
  2. call ascmap $
  3. for %%a in (1.dat) do (
  4.   for /f "usebackq delims= tokens=4 " %%b in ("%%a") do (
  5.     set "str=%%b"
  6.     set "str=!str:%$:~0x01,1%=!"
  7.     set "str=!str:%$:~0x02,1%=!"
  8.     set "str=!str:%$:~0x03,1%=!"
  9.     set "str=!str:%$:~0x1E,1%=!"
  10.     set "str=!str:%$:~0x04,1%= !"
  11.     set "str=!str:%$:~0x05,1%= !"
  12.     set "str=!str:%$:~0x2D,1%=!"
  13.       for %%i in (!str!) do (
  14.         set/a _%%i+=1
  15.         echo %%i 出现 !_%%i!次
  16.       )
  17.    )
  18. )
  19. pause
复制代码

作者: hfg1977    时间: 2011-8-24 20:25

我去找ascmap.
作者: hfg1977    时间: 2011-8-24 20:50

  1. @echo off
  2. call ascmap $
  3. for /f "tokens=* delims=" %%i in ('dir /a-d/b *.dat') do (
  4. echo.正在处理:%%~i&endlocal&setlocal enabledelayedexpansion
  5. for /f "tokens=* usebackq delims=" %%a in ("%%~i") do (
  6. set "str=%%a"
  7. set "str=!str:%$:~0x01,1%= !"
  8. set "str=!str:%$:~0x02,1%= !"
  9. set "str=!str:%$:~0x03,1%= !"
  10. set "str=!str:%$:~0x1E,1%= !"
  11. set "str=!str:%$:~0x04,1%= !"
  12. set "str=!str:%$:~0x05,1%= !"
  13. set str=!str:-=m!
  14. for %%A in (!str!) do (
  15. set/a _%%A+=1
  16. if !_%%A! GEQ 3 (echo %%A 出现!_%%A!次&echo gtr 3 wait del is ...&echo.)
  17. )))
  18. :end ==============================================================
  19. endlocal&echo 按任意键退出&pause>nul
复制代码
你先测试一下
'dir /a-d/b *.dat'  可以改成'dir /a-d/b/s *.dat' 以搜索子文件夹

由于有Hex字符,打个包吧, 额又占用论坛资源了.
作者: playinthesky    时间: 2011-8-24 21:09

回复 16# hfg1977


    运算符不存在,大哥,你是不是用了第三方的工具?我没有此工具,是否上传?
作者: hfg1977    时间: 2011-8-24 21:28

本帖最后由 hfg1977 于 2011-8-24 21:40 编辑

唯一的第三方 就是 ascmap  在本论坛下的,
http://www.bathome.net/thread-12347-1-1.html
ver 1.01.02

以你上传的两个文件测试的.

ascmap 还真不会用,

修改一下就好了,
@echo off
setlocal enabledelayedexpansion&cls            在这里加一句,下面不变
....
作者: playinthesky    时间: 2011-8-24 21:45

回复 18# hfg1977


    好的,谢谢,我去试试看~!
作者: playinthesky    时间: 2011-8-25 11:34

回复 18# hfg1977


    谢谢你,真的,略微修改之后,测试成功!!!!




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