Board logo

标题: [文本处理] [已解决]请教批处理合并数字交集之类 [打印本页]

作者: kkfgef    时间: 2015-9-20 16:03     标题: [已解决]请教批处理合并数字交集之类

本帖最后由 kkfgef 于 2015-9-21 13:20 编辑

有一文件夹下多个文本有类似以下数据
5~22
10~50
15~42
16~25
16~55
88~89
90~101
92~123
102~111
345~456
400~600
457~500
789~800
801~900
999~1234
………………
请帮忙批量合并 为这样的

5~55
88~123
345~600
789~900
999~1234
简单理解就是把有交集的从最小合并到最大的数字,例如:1~5、2~8、 6~7、 3~10=1~10
还有当相聆的数字的也一并合起来,例如:789~800、 801~900=789~900
没符合条件的就不用合并例如:999~1234=999~1234
作者: bailong360    时间: 2015-9-20 17:43

本帖最后由 bailong360 于 2015-9-20 18:17 编辑
  1. @echo off
  2. setlocal enabledelayedexpansion
  3. ::CODE BY zhonghua @bbs.bathome.net
  4. for /f "delims=" %%i in ('dir /a-d /b *.txt') do (
  5.     (for /f "tokens=1,2 delims=~" %%j in (%%~si) do (
  6.         if not defined q1 (
  7.             set /a q1=%%j,q2=%%k,q22=q2+1
  8.         ) else (
  9.             if %%j leq !q22! (
  10.                 if %%k gtr !q2! set /a q2=%%k,q22=q2+1
  11.             ) else (
  12.                 echo !q1!~!q2!
  13.                 set /a q1=%%j,q2=%%k,q22=q2+1
  14.             )
  15.         )
  16.     )
  17.     echo !q1!~!q2!)>$
  18.     move /y $ "%%i"
  19. )
复制代码
看了楼下的代码瞬间觉得自己太弱了 =_=
作者: 回家路上    时间: 2015-9-20 17:57

本帖最后由 回家路上 于 2015-9-20 18:22 编辑
  1. @echo off & setlocal enabledelayedexpansion
  2. for /r %%a in (*.txt) do (
  3. for /f "tokens=1,2 delims=~" %%i in ('sort /+20 "%%a"') do (
  4. if %%j gtr !e! set e=%%j
  5. set /a "1/^!((b-%%j-2)>>31)"&& (set str=!b!~!e!,!str!&set e=%%j)
  6. set b=%%i
  7. ) 2>nul
  8. set str=!b!~!e!,!str!
  9. (for %%i in (!str!) do echo;%%i)>$
  10. move /y $ "%%a"
  11. rem 如果不想覆盖源文件,就将不要上面两行,(for %%i in (!str!) do echo;%%i)>"另一个位置\%%~nxi"
  12. )
  13. pause & exit /b
复制代码

作者: aa77dd@163.com    时间: 2015-9-20 18:13

本帖最后由 aa77dd@163.com 于 2015-9-20 19:48 编辑

概念混淆!   楼主要做的运算是 并集,  而不是交集!

把 批处理文件 和 文本文件放在同一目录
  1. @echo off&setlocal enabledelayedexpansion
  2. (set LOut=')&(set UOut=Z)& rem 在集合最后面加一个假子集 [UOut, UOut] 作为尾部标志
  3. set "U={}" & (call :initSet U)
  4. for %%a in (*.txt) do for /f "tokens=1-2 delims=~" %%a in (%%~sa) do (
  5.     echo %%a,%%b
  6.     set "X={[%%a,%%b]}"
  7.     (call :initSet X)
  8.     call :Union X U U
  9. )
  10. call :Simplify U
  11. call :outputSet U
  12. > result.ini call :getSet U
  13. start result.ini
  14. echo 任意键退出&pause>nul
  15. exit
  16. :Union A B A∪B
  17. (call :copySet %1 A&call :copySet %2 B&call :clearSet R)
  18. set /a "pntA=1,pntB=1,pntR=0"&(set RL0=%LOut%&set RU0=%LOut%)
  19. :UnionLoop
  20. if "!RL%pntR%!"=="!UOut!" (call :copySet R %3)&exit /b
  21. :UnionSch1
  22. if !AU%pntA%! leq !RU%pntR%! set /a "pntA+=1"&goto :UnionSch1
  23. if !AL%pntA%! leq !RU%pntR%! set "RU!pntR!=!AU%pntA%!"
  24. :UnionSch2
  25. if !BU%pntB%! leq !RU%pntR%! set /a "pntB+=1"&goto :UnionSch2
  26. if !BL%pntB%! leq !RU%pntR%! set "RU!pntR!=!BU%pntB%!"
  27. set "intersec=Y"
  28. if !AL%pntA%! gtr !BU%pntB%! (set "intersec=N") else (
  29.   if !BL%pntB%! gtr !AU%pntA%! set "intersec=N")
  30. set /a "pntR+=1"
  31. (call :min !AL%pntA%! !BL%pntB%! RL!pntR!)
  32. if "!intersec!"=="Y" (call :max !AU%pntA%! !BU%pntB%! RU!pntR!) else (
  33.   call :min !AU%pntA%! !BU%pntB%! RU!pntR!)
  34. goto :UnionLoop
  35. exit /b
  36. :copySet src dest
  37. call :clearSet %2
  38. set "i=0"
  39. :copySet.loop
  40. set /a i+=1
  41. for %%i in (%i%) do ( if "!%1L%%i!"=="" (exit /b) else (set %2L%%i=!%1L%%i!&set %2U%%i=!%1U%%i!) )
  42. goto :copySet.loop
  43. exit /b
  44. :min a b min (a,b 以串值调用, min 以变量名调用)
  45. if %1 lss %2 (set %3=%1) else (set %3=%2)
  46. exit /b
  47. :max a b max (a,b 以串值调用, max 以变量名调用)
  48. if %1 gtr %2 (set %3=%1) else (set %3=%2)
  49. exit /b
  50. :outputSet
  51. (set lastout=')
  52. set /p=%1={<nul
  53. if "!%1L1!"=="" echo }&exit /b
  54. set "i=0"
  55. :outputSet.loop
  56. set /a i+=1
  57. for %%i in (%i%) do (
  58.   if "!%1L%%i!"=="" (if %%i neq 1 (echo }) else echo })&exit /b
  59.   if "!%1L%%i!"=="!UOut!" (
  60.     (if %%i neq 1 (echo }) else echo })&exit /b
  61.   ) else if !%1L%%i! gtr !lastout! (
  62.     if !%1L%%i! neq !%1U%%i! (
  63.       set /p=[!%1L%%i!,!%1U%%i!],<nul
  64.     ) else set /p=!%1L%%i!,<nul
  65.     (set lastout=!%1U%%i!)
  66.   )
  67. )
  68. goto :outputSet.loop
  69. exit /b
  70. :clearSet
  71. set "i=0"
  72. :clearSet.loop
  73. set /a i+=1
  74. for %%i in (%i%) do ( if "!%1L%%i!"=="" (exit /b) else (set %1L%%i=&set %1U%%i=) )
  75. goto :clearSet.loop
  76. exit /b
  77. :err
  78. echo 错误, 任意键退出&pause
  79. exit /b
  80. :getUniverseLU
  81. set "universeL=1"
  82. :get_uniLU
  83.   set /a "universeL<<=1"
  84.   if %universeL% lss 0 (set /a "universeU=-(universeL+1), universeL=0"&exit /b) else goto :get_uniLU
  85. exit /b
  86. :Simplify A 仅用于最后输出之前(不再做任何运算), 将相邻子集合并
  87. (call :copySet %1 A)&(set /a pntA=0, pntN=pntA+1)&set "AU0=!LOut!"
  88. :SimplifyLoop
  89. if "!AL%pntN%!"=="!UOut!" (call :copySet A %1)&exit /b
  90. set /a "tt=AL!pntN!-1"
  91. if "!AU%pntA%!" equ "!tt!" (
  92.   set "AU!pntA!=!AU%pntN%!"
  93.   set /a "pntN+=1"
  94. ) else set /a "pntA=pntN,pntN+=1"
  95. goto :SimplifyLoop
  96. exit /b
  97. :initSet
  98. set "%1=!%1: =!" & set "%1=!%1:{=!" & set "%1=!%1:}=!"
  99. set "pnt%1=0" & set "flag=CN"
  100. for %%i in (!%1!) do (
  101.   set "tt=%%i"
  102.   if "!tt:~0,1!"=="[" (
  103.     if "!flag!" equ "L" (echo 集合%1语法错误:%%i&pause&goto :err)
  104.     set "flag=L"
  105.     set /a pnt%1+=1&set "%1L!pnt%1!=!tt:~1!"
  106.   ) else if "!tt:~-1!"=="]" (
  107.     if "!flag!" neq "L" (echo 集合%1语法错误:%%i&pause&goto :err)
  108.     set "flag=R"
  109.     set "%1U!pnt%1!=!tt:~0,-1!"
  110.   ) else if "!flag!" equ "L"  (echo 集合%1语法错误:%%i&pause&goto :err
  111.   ) else set /a pnt%1+=1&set "%1L!pnt%1!=!tt!"&set "%1U!pnt%1!=!tt!"&set "flag=CN"
  112. )
  113. set /a pnt%1+=1&set "%1L!pnt%1!=!UOut!"&set "%1U!pnt%1!=!UOut!"
  114. exit /b
  115. :getSet
  116. (set lastout=')
  117. if "!%1L1!"=="" exit /b
  118. set "i=0"
  119. :getSet.loop
  120. set /a i+=1
  121. for %%i in (%i%) do (
  122.   if "!%1L%%i!"=="" exit /b
  123.   if "!%1L%%i!"=="!UOut!" (
  124.     exit /b
  125.   ) else if !%1L%%i! gtr !lastout! (
  126.     echo !%1L%%i!~!%1U%%i!
  127.     (set lastout=!%1U%%i!)
  128.   )
  129. )
  130. goto :getSet.loop
  131. exit /b
复制代码

作者: aa77dd@163.com    时间: 2015-9-20 18:34

回复 3# 回家路上

4 楼的代码 引用 于 此处 [挑战]批处理求集合的交集与并集
作者: 回家路上    时间: 2015-9-20 18:37

本帖最后由 回家路上 于 2015-9-20 18:39 编辑

回复 4# aa77dd@163.com


哦,了然了。论坛真是啥宝贝都有,关键是你竟然能用明白(⊙﹏⊙)b
二三楼的代码好像也没问题。
作者: aa77dd@163.com    时间: 2015-9-20 18:39

本帖最后由 aa77dd@163.com 于 2015-9-20 19:02 编辑

回复 6# 回家路上

我没想多动脑筋了,  有现成的就贴吧,  速度很慢

http://bbs.bathome.net/redirect.php?goto=findpost&ptid=7612&pid=50008&fromuid=71942 中的代码由于使用了多处  for /L 循环,   而 exit /b 并不能实质上 BREAK 掉这种循环, 所以导致代码运行慢,  改成 goto 后好多了
作者: kkfgef    时间: 2015-9-20 20:02

  1. 236095488~236096511
  2. 244613120~244617471
  3. 244617472~244617727
  4. 244617728~244624127
  5. 244624128~244624383
  6. 244624384~244625919
  7. 244625920~244626175
  8. 244626176~244631807
  9. 244631808~244632063
  10. 244632064~244644351
  11. 244644352~244644607
  12. 244644608~244645887
  13. 455852032~455852287
  14. 455852544~455860223
  15. 989687808~989688063
  16. 989688064~989691903
  17. 992195584~992196607
  18. 992196608~992197375
  19. 992197376~992197887
  20. 992197888~992198911
  21. 992198656~992198911
  22. 992198912~992199167
  23. 992198912~992200191
  24. 992200192~992200447
  25. 992200448~992203007
  26. 992203008~992203263
  27. 992203264~992204799
  28. 1025248512~1025248767
  29. 1025248512~1025249023
  30. 1032587776~1032588543
  31. 1032816640~1032816895
  32. 1032816640~1032817151
  33. 1032816896~1032817151
  34. 1032816896~1032817407
  35. 1032817152~1032817407
  36. 1032817152~1032818175
  37. 1032817920~1032818175
  38. 1032817920~1032818687
  39. 1033001984~1033002239
  40. 1033001984~1033002495
  41. 1033002240~1033002495
  42. 1033002240~1033005055
  43. 1033004800~1033005055
  44. 1033013760~1033014015
  45. 1038834432~1038834687
  46. 1859217152~1859217407
  47. 1871978496~1871979519
  48. 1871997952~1871998463
  49. 1872057344~1872060415
  50. 1872098304~1872101375
  51. 1901395968~1901425663
  52. 1901425664~1901425919
  53. 1901425920~1901428735
  54. 1902616576~1902624767
  55. 1902844672~1902845951
  56. 1902854144~1902854399
  57. 1902854144~1902857215
  58. 1902857216~1902857471
  59. 1902857472~1902862335
  60. 1902869504~1902872575
  61. 1902873856~1902877439
  62. 1902878464~1902879231
  63. 1902880000~1902881791
  64. 1902882048~1902883583
  65. 1902886144~1902887679
  66. 1902887936~1902888959
  67. 1902892032~1902892543
  68. 1902892288~1902895615
  69. 1902896128~1902897919
  70. 1902898432~1902898943
  71. 1902898944~1902899199
  72. 1902898944~1902901247
  73. 1946530048~1946537983
  74. 1947236352~1947241983
  75. 1947241984~1947242239
  76. 1947242240~1947250687
  77. 1958889984~1958890239
  78. 1958932480~1958932735
  79. 2004402176~2004418559
  80. 2005696512~2005701119
  81. 2005701120~2005701375
  82. 2005701376~2005702143
  83. 2005702144~2005702399
  84. 2005702400~2005712895
  85. 2005839872~2005852159
  86. 2005852160~2005852415
  87. 2005852416~2005860351
  88. 2018951168~2018967551
  89. 2026173952~2026174463
  90. 2026175488~2026175743
  91. 2033398784~2033399807
  92. 2046873600~2046874623
  93. 2046874624~2046875391
  94. 2046875392~2046875647
  95. 2067817472~2067818495
  96. 2067886080~2067888127
  97. 2069377024~2069378303
  98. 2069378304~2069378559
  99. 2069378560~2069379071
  100. 2069473536~2069473791
  101. 2103140352~2103140607
  102. 2103140352~2103140863
  103. 2103140608~2103140863
  104. 2103140608~2103141119
  105. 2103141120~2103141375
  106. 2103141376~2103143679
  107. 2103143680~2103144191
  108. 2103144192~2103150591
  109. 2103150592~2103151615
  110. 2103151616~2103152383
  111. 2103152128~2103152383
  112. 2103152128~2103152639
  113. 2103152384~2103152639
  114. 2103173120~2103173375
  115. 2103173888~2103174143
  116. 2103173888~2103175423
  117. 2103175168~2103175423
  118. 2103175168~2103175679
  119. 2103175424~2103175679
  120. 2103175424~2103178495
  121. 2103178752~2103181311
  122. 2103371776~2103372031
  123. 2103372288~2103373311
  124. 2103373312~2103373567
  125. 2103373568~2103373823
  126. 2638074112~2638075391
  127. 3070885888~3070886911
  128. 3070886912~3070887167
  129. 3070887168~3070889215
  130. 3070889216~3070889471
  131. 3070889472~3070889983
  132. 3070915328~3070921727
  133. 3070921728~3070921983
  134. 3070921984~3070951423
  135. 3071852544~3071860223
  136. 3071860480~3071868927
  137. 3073949696~3073956607
  138. 3073956608~3073956863
  139. 3073956864~3073964799
  140. 3073964800~3073965055
  141. 3073965056~3073966079
  142. 3074066944~3074067455
  143. 3085560832~3085561855
  144. 3085593600~3085594111
  145. 3085863936~3085864447
  146. 3086007296~3086008319
  147. 3395876864~3395877887
  148. 3395941376~3395941631
  149. 3395941632~3395941887
  150. 3525758976~3525763071
  151. 3546327040~3546327807
  152. 3546327552~3546327807
  153. 3546327552~3546329087
  154. 3549161984~3549162495
  155. 3549617408~3549617663
  156. 3658432512~3658432767
  157. 3658432512~3658433023
  158. 3658432768~3658433023
  159. 3658432768~3658433279
  160. 3658433024~3658433279
  161. 3658433024~3658433535
  162. 3658433280~3658433535
  163. 3658433280~3658437119
  164. 3658436864~3658437119
  165. 3658437120~3658437375
  166. 3658437376~3658437631
  167. 3658437376~3658437887
  168. 3658437632~3658437887
  169. 3658437632~3658438143
  170. 3658437888~3658438143
  171. 3658437888~3658438655
  172. 3658438400~3658438655
  173. 3658438400~3658438911
  174. 3658438656~3658438911
  175. 3658438656~3658439167
  176. 3658438912~3658439167
  177. 3658438912~3658439423
  178. 3658439168~3658439423
  179. 3658439168~3658440447
  180. 3658440192~3658440447
  181. 3658440448~3658440703
  182. 3682828288~3682828543
  183. 3682828288~3682829311
  184. 3682829056~3682829311
  185. 3682829056~3682829567
  186. 3682829568~3682829823
  187. 3682829824~3682832639
  188. 3682832384~3682832639
  189. 3682832384~3682833151
  190. 3682832896~3682833151
  191. 3682832896~3682834943
  192. 3682834688~3682834943
  193. 3682834688~3682836479
  194. 3682836224~3682836479
  195. 3707358208~3707358463
  196. 3719067648~3719069439
  197. 3719523328~3719524351
  198. 3746106368~3746107391
  199. 3746153472~3746154495
复制代码
很是奇怪,当数字达到这些倍数的时候,用了上面几位的都没能得出结果呢
我的结果是
  1. 236095488~236096511
  2. 244613120~244645887
  3. 455852032~455852287
  4. 455852544~455860223
  5. 989687808~989691903
  6. 992195584~992204799
  7. 1025248512~1025249023
  8. 1032587776~1032588543
  9. 1032816640~1032818687
  10. 1033001984~1033005055
  11. 1033013760~1033014015
  12. 1038834432~1038834687
  13. 1859217152~1859217407
  14. 1871978496~1871979519
  15. 1871997952~1871998463
  16. 1872057344~1872060415
  17. 1872098304~1872101375
  18. 1901395968~1901428735
  19. 1902616576~1902624767
  20. 1902844672~1902845951
  21. 1902854144~1902862335
  22. 1902869504~1902872575
  23. 1902873856~1902877439
  24. 1902878464~1902879231
  25. 1902880000~1902881791
  26. 1902882048~1902883583
  27. 1902886144~1902887679
  28. 1902887936~1902888959
  29. 1902892032~1902895615
  30. 1902896128~1902897919
  31. 1902898432~1902901247
  32. 1946530048~1946537983
  33. 1947236352~1947250687
  34. 1958889984~1958890239
  35. 1958932480~1958932735
  36. 2004402176~2004418559
  37. 2005696512~2005712895
  38. 2005839872~2005860351
  39. 2018951168~2018967551
  40. 2026173952~2026174463
  41. 2026175488~2026175743
  42. 2033398784~2033399807
  43. 2046873600~2046875647
  44. 2067817472~2067818495
  45. 2067886080~2067888127
  46. 2069377024~2069379071
  47. 2069473536~2069473791
  48. 2103140352~2103152639
  49. 2103173120~2103173375
  50. 2103173888~2103178495
  51. 2103178752~2103181311
  52. 2103371776~2103372031
  53. 2103372288~2103373823
  54. 2638074112~2638075391
  55. 3070885888~3070889983
  56. 3070915328~3070951423
  57. 3071852544~3071860223
  58. 3071860480~3071868927
  59. 3073949696~3073966079
  60. 3074066944~3074067455
  61. 3085560832~3085561855
  62. 3085593600~3085594111
  63. 3085863936~3085864447
  64. 3086007296~3086008319
  65. 3395876864~3395877887
  66. 3395941376~3395941887
  67. 3525758976~3525763071
  68. 3546327040~3546329087
  69. 3549161984~3549162495
  70. 3549617408~3549617663
  71. 3658432512~3658440703
  72. 3682828288~3682836479
  73. 3707358208~3707358463
  74. 3719067648~3719069439
  75. 3719523328~3719524351
  76. 3746106368~3746107391
  77. 3746153472~3746154495
复制代码

作者: kkfgef    时间: 2015-9-20 20:03

综合上面几个方法,都没有得出正确的结果
作者: CrLf    时间: 2015-9-20 20:48

本帖最后由 CrLf 于 2015-9-20 20:49 编辑

回复 9# kkfgef


    超出计算上限了,这个表你应该早给我们
作者: 回家路上    时间: 2015-9-20 20:49

本帖最后由 回家路上 于 2015-9-20 21:14 编辑

超过了整数的最大限制,已经不是整数了,这种级别的光加减法都得写各自的函数,比较也得用字符串比较了,没想到这么大
当然一个文件如果从1到这么到,最后结果也不可能一个字符串存储了。
作者: 回家路上    时间: 2015-9-20 22:26

同样的逻辑用JS实现一下吧。还是保存为bat,放在txt同一目录运行。
  1. @if(0)==(0) echo off&dir /b *.txt|cscript -nologo -e:jscript "%~f0"&pause&exit /b&@end
  2. function compareInt(a, b){
  3. return parseInt(a) > parseInt(b);
  4. }
  5. function $bool(a){
  6. return !a || a=="undefined";
  7. }
  8. var fso = new ActiveXObject("Scripting.FileSystemObject");
  9. var files = WScript.StdIn.ReadAll().split("\r\n");
  10. for (var i=0; i<files.length; i++) {
  11. var fn=files[i];
  12. if(!fn) continue;
  13. WSH.Echo("处理文件:" + fn);
  14. var content = fso.OpenTextFile(fn,1).ReadAll()
  15. var begin,end,result="";
  16. content.replace(/(.*)(?:\r\n|$)/g, function($0,$1){
  17. var be=$1.split("~");
  18. if($bool(begin)) begin = be[0];
  19. if($bool(end)) end = be[1];
  20. if (be[0]-end-1>0) {
  21. result += begin + "~" +end + "\r\n";
  22. begin = be[0];
  23. }
  24. if(compareInt(be[1], end)) end = be[1];
  25. });
  26. result += begin + "~" +end;
  27. // WSH.Echo(result);
  28. fso.CreateTextFile(fn,2).Write(result);
  29. }
复制代码

作者: bailong360    时间: 2015-9-20 22:26

回复 8# kkfgef
  1. @echo off
  2. for /f "delims=" %%i in ('dir /a-d /b *.txt') do (
  3.     gawk "/^#<awk/,/^#>awk/{if(!/^#/)print}" %0|gawk -F "~" -f "-" "%%i">$
  4.     move /y $ "%%i"
  5. )
  6. exit /b
  7. #<awk
  8. {if(NR==1){
  9.         q[1]=$1;q[2]=$2
  10.     } else {
  11.         if($1<=q[2]+1){
  12.             if($2>=q[2]) q[2]=$2
  13.         } else {
  14.             print q[1]"~"q[2]
  15.             q[1]=$1;q[2]=$2
  16.         }
  17.     }
  18. }
  19. END{print q[1]"~"q[2]}
  20. #>awk
复制代码
需要第三方gawk支持




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