![Board logo](images/default/logo.gif)
标题: [文本处理] 如何提高批处理删除重复内容文本的效率? [打印本页]
作者: playinthesky 时间: 2013-3-11 22:54 标题: 如何提高批处理删除重复内容文本的效率?
多个文本内有重复的字符,我设定一旦有重复的,就将其所含内容的整个文本删除,但是效率非常低下,1000个txt文档,就需要好几分钟。而我这里有上万个,求高手能否改进?- @echo off&setlocal enabledelayedexpansion
- for %%a in (*.txt) do (
- for /f "usebackq delims=. tokens=2,*" %%b in (%%a) do (
- set "str=%%b"
- set "str=!str: =!"
- for %%i in (!str!) do (
- set/a _%%i+=1
- if !_%%i! gtr 2 echo %%a>>1.txt 2>nul
- )
- set _%%i=
- )
- )
- pause
复制代码
我这里写的是读入 1.txt
然后在读入的内容中发现
33303564545.txt
33303564545.txt
33303564545.txt
33303564545.txt
999999999999999.txt
999999999999999.txt
999999999999999.txt
以上是ECHO出来的,就是条件循环判断正确的,就其删除,但是会出现好几次,有上万个这样的文件,所以我想先写入一个文本,然后再根据文本上的地址删除,不知道有没有更加高效的方法,做到可以让删除的提示不出现那么多次,2>NUL 只是假象。。
意思就是换成 DEL 里面的路径文件,依旧效率不高,最好能只显示一次,然后一次性删除,不符合条件的文本。因为有上万个,希望能高效一点,求好心人解决!
运行是正常的,就是效率很低下。。
作者: playinthesky 时间: 2013-3-11 23:13
通过在BATHOME的学习,慢慢的学会写代码,希望大家再帮帮我,自己顶一下。
作者: playinthesky 时间: 2013-3-11 23:16
因为批处理每个都要历遍,但是为什么删除的时候,循环要检查好几次?
作者: wankoilz 时间: 2013-3-11 23:30
这种情况,上万个文件用纯批来处理估计有点慢哦
作者: terse 时间: 2013-3-11 23:32
这样提高点不- @echo off&setlocal enabledelayedexpansion
- (for %%i in (*.txt) do (
- set "a="
- for /f "delims=" %%j in ('sort "%%i"') do (
- if not defined a (
- if "!str!" == "%%j" set a=a&echo del "%%i"
- set "str=%%j"
- )
- )
- ))>$.#
- start "" "notepad" "$.#"
- pause
复制代码
作者: playinthesky 时间: 2013-3-11 23:35
回复 5# terse
我那个是有格式的,所以必须按照上面的那种分隔符来,我去试试看!最最主要上万个。。
作者: playinthesky 时间: 2013-3-11 23:36
回复 5# terse
是加在最后?对么?试试看!
作者: terse 时间: 2013-3-11 23:47
回复 terse
我那个是有格式的,所以必须按照上面的那种分隔符来,我去试试看!最最主要上万个。 ...
playinthesky 发表于 2013-3-11 23:35 ![](http://bbs.bathome.net/images/common/back.gif)
有固定格式的话 把第二FOR 替换这样试- for /f "tokens=2 delims=." %%j ..........
复制代码
作者: playinthesky 时间: 2013-3-11 23:56
回复 8# terse
超级高!!!非常快!!!谢谢高手,那我就是要那个文本文件改写成.BAT就可以吧?可不可以直接一点的。。
作者: CrLf 时间: 2013-3-11 23:59
纯批的话我会这样:- @echo off
- findstr . *.txt|sort /o tmp.$
- (for /f "tokens=1* delims=:" %%a ni (tmp.$) do (
- set "str=%%a"
- setlocal enabledelayedexpansion
- if !last!==!str! del "%%a"
- endlocal
- set last=%%a
- )) 2>nul
- pause
复制代码
作者: playinthesky 时间: 2013-3-11 23:59
本帖最后由 playinthesky 于 2013-3-12 00:07 编辑
回复 8# terse
我想加入计数器,在第二个FOR里面,重复内容5个以上的时候,删除文本,你的这个版本真心好!
作者: playinthesky 时间: 2013-3-12 00:01
回复 10# CrLf
是纯批处理,可不可以加入一个计数器,等到重复到一定个数的时候删除?求教。
作者: playinthesky 时间: 2013-3-12 00:03
回复 5# terse
高手,加个计数器,等到重复两个或者三个的时候,直接删除。谢谢![](images/smilies/default/smile.gif)
作者: playinthesky 时间: 2013-3-12 00:05
回复 5# terse
重复的数量上有限定要求,加入计数器在哪里比较好?
作者: CrLf 时间: 2013-3-12 00:19
本帖最后由 CrLf 于 2013-3-12 00:39 编辑
文件又多又大的话,用 vbs 会快很多- Const [路径]="." '这里设置路径
- Const [重复次数]="1" '代表重复达到多少次就删除
- Set fso = CreateObject("scripting.filesystemobject")
-
- For Each file In fso.GetFolder([路径]).Files
- If LCase(fso.GetExtensionName(file)) = "txt" Then
- If reTest(fso.OpenTextFile(file).ReadAll) Then
- file.Delete
- End If
- End If
- Next
-
- Function reTest(text)
- Set re = New RegExp
- re.Global = True
- re.Pattern = "\n(\S+)(?:(?:\n.*)?\n\1){" & [重复次数] & ",}\n"
- reTest = re.Test(vbCrLf & text & vbCrLf)
- End Function
复制代码
作者: playinthesky 时间: 2013-3-12 00:26
回复 15# CrLf
大哥,我的意思是在我最初写的代码里,GTR 3 或者 4 或者 5 可以吗?或者 LSS 也成,加个计数器,谢谢你!!你们的代码都很高深,我不知道如何插入?谢谢了。。我要计算重复大于5个的文件删除之类,可以实现吗?
作者: playinthesky 时间: 2013-3-12 00:29
回复 15# CrLf
问题是有固定格式的。。对不起,已经很烦扰你了。。我需要 用 . 作为分割,然后把空格消掉,所以才在顶楼这样写。。。谢谢。。
作者: CrLf 时间: 2013-3-12 00:40
回复 17# playinthesky
我都用中文变量名了还看不出来怎么设置重复次数吗...
作者: playinthesky 时间: 2013-3-12 01:01
本帖最后由 playinthesky 于 2013-3-12 06:08 编辑
回复 18# CrLf
重复次数,我理解的,我的意思是它那个文件上有格式方面的限制,比方说ABCDABCD,如果说重复的话,A不是出现了两次,但是我是一个数组,所有是ABC为一个组合出现,需要计数,所以用了TOKENS和DELIMS,
作者: playinthesky 时间: 2013-3-12 01:05
本帖最后由 playinthesky 于 2013-3-12 06:07 编辑
回复 10# CrLf
作者: wankoilz 时间: 2013-3-12 09:21
本帖最后由 wankoilz 于 2013-3-12 09:23 编辑
15楼pattern中 (?:\n.*) 我不太明白,按我的理解我觉得应该加上一个回车符 (?:\r\n.*)
还望解答!
作者: Herculeslove 时间: 2013-3-12 19:21
回复 5# terse
能否历遍子目录 ? 我用dir /a-d/b/s *.txt 一直出错。
作者: BAT-VBS 时间: 2013-3-12 21:08
回复 22# Herculeslove - @echo off&setlocal enabledelayedexpansion
- (for /f "delims=" %%i in ('dir /a-d/b/s *.txt') do (
- set "a="
- for /f "delims=" %%j in ('sort "%%i"') do (
- if not defined a (
- if "!str!" == "%%j" (
- set a=a
- echo del "%%i"
- )
- set "str=%%j"
- )
- )
- ))>$.#
- start "" "notepad" "$.#"
复制代码
作者: CrLf 时间: 2013-3-12 21:52
回复 21# wankoilz
.* 不跨行是针对 \n 的,\r 会被包含在 .* 或 \S+ 中,所以对结果没有影响,但若要严谨确实应该加上 \r
作者: wankoilz 时间: 2013-3-12 23:16
回复 24# CrLf
\S 与任何非空白的字符匹配。等价于"[^ \f\n\r\t\v]"。
按照帮助文档的说法,\S应该不包含\r才对啊
作者: CrLf 时间: 2013-3-12 23:38
回复 25# wankoilz
噢,那也许 regexp 里的 \n 实际上匹配的是 \r?\n 吧?
作者: wankoilz 时间: 2013-3-13 00:04
我还是觉得该加一个\r
欢迎光临 批处理之家 (http://bbs.bathome.net/) |
Powered by Discuz! 7.2 |