Board logo

标题: [文本处理] [已解决]批处理怎样比较多个文本并删除特定部分内容相同的重复文件? [打印本页]

作者: playinthesky    时间: 2011-6-24 23:04     标题: [已解决]批处理怎样比较多个文本并删除特定部分内容相同的重复文件?

本帖最后由 pcl_test 于 2016-7-14 17:04 编辑

首先先谢谢各位版主,对我之前问题的热心。我想说声:谢谢。这里学习一段时间,想请教问题。

多个文本,大概有几千个。

文本 A的内容:
ABS11 Moves  <7C-4C7J-6H7A-6C8J-7J8A-7A6G-6F7A-7G1J-2H1A-2C2G-2F0A-0B2J-4H0B-3B6H-5F4D-4E6F-6E7G-5G6E-6D5G-5F6D-6C5F-7F0J-0I4E-4F1H-1F2C-4D0I-7I4D-6E5J-4I1C-6C7H-5H7F-7I7J-7I4F-4G2H-4G3B-3G7I-7E3G-4G7E-6E6C-7C5H-7H4C-0C6E-6A0C-0G6A-6C7C-7E1F-1I4G-1G1I-2I1G-2G2I-2H0G-8G6C-6E8G-8J4I-5J7E-7C6E-4E5A-4B4E-4D8D-8E4D-2D7C-4C2D-4D8E-8F3J-4I8F-8G2H-3H8G-7G7H-8H0D-0E4D-4E0E-0F8H-8D0F-1F2F-2E2G-3G3H-2H1F-2F2E-3E2F-3F8D-2D4B-5C2H-2A4A-4B4E-8E7G-8G8E-7E4C-4D3E-3D4D-2D3D-2D3G-7G7E-4E4B-5B4E-6E3A-4B2D-2C8G-8H2A-2B4B-3A2C-3C7G-2G3C-3B2G-2B3B-2B3A-4B6E-6H8H-8I6H-6B5B-5A6B-6A5A-5B6A-6I8J-7J6I-8I7J-7F2B-3B4B-3C8I-8B5B-5A8B-8F7F-4F8F-8E5A-5B8E-3E3F-2F3E-3C2F-2G3C-3F4F-4E3F-2F2G-1G2F-8F1G-1H8F-8B5B-5A8B-8E4E-4D8E-8D4D-4F8D-5D5A-5B3B-4B5B-4B5D-4D4B-5B4D-4F1H-2H4F-2F2H-1H2F-2C1H-1I4H-2J5C-4B2C-2B5B-5A2B-4B1I-2I4I-3J2I-3I2J-0H3I-2I4B-4F5A-5B4F-5F> Ends CommentsEnd

文本 B的内容
TBS1212 Moves <7C-4C7J-6H7A-6C8J-7J8A-7A1J-2H6D-6E2G-2F1A-0C0G-0F1C-2C2H-1F0A-0B2J-4H7A-7G0J-0G0B-3B5J-4I6C-5E7H-8H7G-7J6H-7J5E-6G8H-6H6A-8C1F-0D2C-2B7J-8H6G-5E0D-1F5E-4G6H-5H3B-3F1F-2H4G-2H5H-2H3F-3E0F-0E2B-0B2F-2E3E-2E2H-2F2E-1E2F-2A3A-4B0E-1E0B-0G1E-0E0G-0J4H-2J0C-1A0E-1E0J-1J1E-1D4C-7C1D-1C8C-6A1H-4H7C-7B8H-6I1J-1G6I-5G1G-4G5G-6E6A-4C6E-8D7B-5B2A-2C1A-2C1C-2C5B-5C2J-0H4D-4E8D-7F5C-2C4J-5J4G-1G7F-5G1G-1J5J-5I4E-4F4H-4C4A-3A5G-6E2C-1C6E-4F1J-6J4F-6E6J-6F6E-4D1C-1D4D-3F2D-2E4C-4E6F-6E3F-4D6E-5E4E-4H5E-5C4H-7H4B-3C7H-7E5A-4B8G-8F1D-3D5I-5J5C-5D8F-8E3A-4A8E-8D3D-1D8D-7D1D-1J5J-5I1J-1D7D-6D5D-5A6D-6C1D-3D5I-5J5A-5D5J-4J5D-8D7E-8E8D-5D4I-3H4A-5A6C-6B5A-4A4D-3F5D-5C6B-5B4A-3A8E-3E3A-4A3E-3C5C-4C3C-1C3D-3H3F-5E4C-4E1C-1E2E-2F0H-2F3H-3B1E-1B3B-3D5E-7D3D-1D7D-6F1D-4D4J-5J4E-6E1B-1I4B-5C1I-4I4A-3A4I-3I3A-4A5B-6B4A-4B3I-4I4B-3B4I-5I3B-4B2F-0H4B-4A5I-3I4A-4B6F-4G4D-6D6B-7B6D-6A3I-4I4B-3B7B-6B6A-5A6B-5B5C-4B5B-4B3B-3C4G-3E6E-5E5J-4J5E-4E4I-3I> Ends CommentsEnd

文本 C
。。。
文本 ZF
。。。

文本 N
T545454  Moves  <7C-4C7J-6H7A-6C8J-7J8A-7A1J-2H2D-2E6G-6F7A-7G7H-8H7G-6G8H-8I1A-2C3J-4I1C-0C0J-1J0A-1A8I-6I6G-5G6H-7F0C-0G6I-6D6C-4B6F-6E5G-5F1H-1D0G-0E7F-8D2C-3E7J-7C1A-1C2J-4H4C-3C7C-7F2A-4C7F-5F3E-5F1J-1F5F-3E1F-4F3E-2G4F-4D4B-2C4D-2D0E-0J4I-5H3A-4B6E-5E3C-3H6D-5D3H-3B2D-3D2E-2F4H-2F3B-2B5D-7D2C-1E3D-5D1E-3F7D-7H2B-2D>


本来可以用 软件 通过 CRC或 md5校验 查出不同的,但是因为是要比较部分内容,所以没办法用。需要比较的那个部分是 "<   >" 之间的内容,如果在数个文本中找到相同的中间 "< >" 内一样的,就删除重复内容的文本,只有一个。

只会比较两个,要是让一个和多个比较,再重复,只留一个,不会弄,能教我吗?
  1. (type "%file1%"&echo.&type "%file2%")>"%outfile%"
  2. cd.>"%outfile%.bak"
  3. for /f "delims=" %%i in ('type "%outfile%"') do (if not defined %%i set %%i=A & echo %%i>>"%outfile%.bak")
  4. move /y "%outfile%.bak" "%outfile%"
复制代码

作者: slore    时间: 2011-6-24 23:17

如果是你的样例的话。。。

将文件比较部分提取。。。文件名为Moves前面的名字。。。。
然后用 软件 通过 CRC或 md5校验 查出不同的。。。
最后将文件名字样写入即可。。。
作者: playinthesky    时间: 2011-6-24 23:19

问题是  MOVES 前面 也有 不同的 内容  " ABS11 Moves  < "
作者: playinthesky    时间: 2011-6-24 23:20

MOVES 前面的字母和数字是文本中的内容 ,所以 难办 。
作者: slore    时间: 2011-6-25 09:15

。。。我的意思你生成一份没有MOVES前面的文本。。。文件名包含这内容。。。
全是<...>的文本,然后比较完后,生成一份 从文件名中拿出MOVES前面的内容然后和MOVES + 文本内容<...> Ends CommentsEnd
作者: batman    时间: 2011-6-25 10:05

从楼主提供的文本格式来看,所有的文本都只有一行,而且字符数也没有超出8192的批处理上限,下面的代码请先测试成功了再用:
  1. @echo off
  2. for %%a in (*.txt) do (
  3.   for /f "usebackq tokens=2 delims=<>" %%b in ("%%a") do (
  4.     if defined "%%b" (
  5.       del /q "%%a"
  6.       ) else (
  7.       set ""%%b"=a"
  8.     )
  9.   )
  10. )
复制代码

作者: playinthesky    时间: 2011-6-25 13:32

测试貌似有点错误,我想询问一下,8293是文本的大小吗?还有就是万一文件名中有字段中间是两个空格,TAKEN的数目是不是延后?

比方说 ABC  DD    DD|SSD-DSDSD-DSD| COMMAND
因为ABC 后面是两个空格,而DD后面是3个空格,这样的话,开始处理对比后面内容的时候是不是就是
takens=5 了?
作者: batman    时间: 2011-6-25 14:23

7# playinthesky
已经在代码中指定了分隔符为<和>,空格已经不是分隔符了,所以tokens一直为2。。。
作者: Batcher    时间: 2011-6-25 14:39

7# playinthesky


不是文本大小,是单行长度。
作者: playinthesky    时间: 2011-6-25 15:45

9# Batcher

那么再请教一下,能否让分隔符定义成自己想要到字符,比方
文件内容是
abc dddd  Moves | 2D-2E1H-2H7C-4C2J-4H4C-4G3J-4I2A-4C1J-3I4G-4F0J-1J1A-3B8J-8I7A-6C8I-5I6D-6E7J-6H8A-7A5I-5F4D-4E6H-4G7A-7D6G-6F7D-3D2H-3H0A-1A6F-6E4C-6E7H-6H1C-1F5F-5G6E-4C5G-5B1F-1B6H-6A5A-4B3H-3B3D-3B6A-8A3B-3I5B-5D3I-3G4G-6F3G-2G5D-7D1B-0B1J-3J2G-5G7D-7A5G-5A8A-5A6C-7A5A-5D7A-6C5D-7D1A-1D3J-3G6C-7E7D-3D7E-5F6F-5H1D-1J3G-3J1J-3J4J-3J4F-3F3J-4J0B-0G8G-8F3F-1F4I-3H0G-4G3H-4I5F-3G3D-2D1F-2F2D-2F2E-2F5H-6F4G-4F6F-5D2F-2G5D-4F4E-4F4J-3J0D-0E3J-3I2G-2H3I-3J4F-4G4H-2J4G-5G2J-4H2H-2I6J-8H3G-1H3J-4J2I-3I8H-6J1H-3G8F-8E5G-5H8E-8D5H-5I6J-8H3I-4I5J-4I5I-4I4J-5J3G-5H8D-8C5H-7I Ends Comments

文本中没有 "< >" 变成 moves | 和 ends comments 之间的内容比较
  1. @echo off
  2. for %%a in (*.mxq) do (
  3.   for /f "usebackq tokens=3 delims= "%~moves""%~ends comments" %%b in ("%%a") do (
  4.       if defined "%%b" (
  5.         del /q "%%a
  6.         ) else (
  7.          set ""%%b"=a"
  8.       )
  9.   )
复制代码
如果是完全相同则删除,中间内容如果不是完全相同就保留,我看了论坛提供的FOR语句详解,但是没有弄明白 TAKENS 和 DELIMS的对应关系。取得MOVES 和 ends comments 中间的比较如何操作,或者说,任意文本内的截取

比方说

文本A内容:

我爱北京天安门。

文本B内容:

我爱北方的天空啊门。

文本C内容:

我爱批处理门。

文本D内容:

我爱北BAT之家空啊门。

文本E内容:

我爱北京天安门。

文本F内容:

我爱北京天安门。

用批处理查询文本的内容,达到的效果就是要删除 在“我爱”和“门”之间完全相同的文本。

要是运行下去的话,应该是文本E和文本F自动被删除了。

能解决吗?
作者: playinthesky    时间: 2011-6-25 15:47

tokens= 的 字符 容量是如何计算的?万一是字的话,怎么解决,求教。
作者: Batcher    时间: 2011-6-25 16:15

10# playinthesky


可以考虑把moves | 和 ends comments 替换成一个文本中不会出现的特殊字符,然后用这个特殊字符作为delims
作者: playinthesky    时间: 2011-6-25 16:55

12# Batcher
好的,谢谢指点,我试试看。
作者: playinthesky    时间: 2011-6-25 22:08

12# Batcher


我成功处理了,谢谢BAT大侠的提示!!
作者: pcl_test    时间: 2016-7-14 17:20

  1. //&cls&dir /a-d/b *.txt|cscript -nologo -e:jscript "%~f0"&pause&exit
  2. var fso = new ActiveXObject('Scripting.Filesystemobject');
  3. var arr={}, n=0;
  4. while(!WSH.StdIn.AtEndOfStream){
  5.     var file = WSH.StdIn.ReadLine();
  6.     try{
  7.         var str = fso.OpenTextFile(file, 1).ReadAll().match(/<([^>]+)>/)[1];
  8.         arr[str]?arr[str]+=fso.GetFile(file).Name+'|':arr[str]=fso.GetFile(file).Name+'|';
  9.     }catch(e){}
  10. }
  11. for(var a in arr){
  12.     if(arr[a].split(/\|/).length >= 2){
  13.         n++;
  14.         WSH.Echo(n+': '+arr[a].slice(0, -1));
  15.     }
  16. }
复制代码





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