标题: [文本处理] [已解决]请教批处理合并数字交集之类 [打印本页]
作者: 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 编辑
- @echo off
- setlocal enabledelayedexpansion
- ::CODE BY zhonghua @bbs.bathome.net
- for /f "delims=" %%i in ('dir /a-d /b *.txt') do (
- (for /f "tokens=1,2 delims=~" %%j in (%%~si) do (
- if not defined q1 (
- set /a q1=%%j,q2=%%k,q22=q2+1
- ) else (
- if %%j leq !q22! (
- if %%k gtr !q2! set /a q2=%%k,q22=q2+1
- ) else (
- echo !q1!~!q2!
- set /a q1=%%j,q2=%%k,q22=q2+1
- )
- )
- )
- echo !q1!~!q2!)>$
- move /y $ "%%i"
- )
复制代码
看了楼下的代码瞬间觉得自己太弱了 =_=
作者: 回家路上 时间: 2015-9-20 17:57
本帖最后由 回家路上 于 2015-9-20 18:22 编辑
- @echo off & setlocal enabledelayedexpansion
- for /r %%a in (*.txt) do (
- for /f "tokens=1,2 delims=~" %%i in ('sort /+20 "%%a"') do (
- if %%j gtr !e! set e=%%j
- set /a "1/^!((b-%%j-2)>>31)"&& (set str=!b!~!e!,!str!&set e=%%j)
- set b=%%i
- ) 2>nul
- set str=!b!~!e!,!str!
- (for %%i in (!str!) do echo;%%i)>$
- move /y $ "%%a"
- rem 如果不想覆盖源文件,就将不要上面两行,(for %%i in (!str!) do echo;%%i)>"另一个位置\%%~nxi"
- )
- pause & exit /b
复制代码
作者: aa77dd@163.com 时间: 2015-9-20 18:13
本帖最后由 aa77dd@163.com 于 2015-9-20 19:48 编辑
概念混淆! 楼主要做的运算是 并集, 而不是交集!
把 批处理文件 和 文本文件放在同一目录- @echo off&setlocal enabledelayedexpansion
- (set LOut=')&(set UOut=Z)& rem 在集合最后面加一个假子集 [UOut, UOut] 作为尾部标志
-
- set "U={}" & (call :initSet U)
-
- for %%a in (*.txt) do for /f "tokens=1-2 delims=~" %%a in (%%~sa) do (
- echo %%a,%%b
- set "X={[%%a,%%b]}"
- (call :initSet X)
-
- call :Union X U U
- )
- call :Simplify U
- call :outputSet U
-
- > result.ini call :getSet U
- start result.ini
- echo 任意键退出&pause>nul
- exit
-
-
-
- :Union A B A∪B
- (call :copySet %1 A&call :copySet %2 B&call :clearSet R)
- set /a "pntA=1,pntB=1,pntR=0"&(set RL0=%LOut%&set RU0=%LOut%)
- :UnionLoop
- if "!RL%pntR%!"=="!UOut!" (call :copySet R %3)&exit /b
- :UnionSch1
- if !AU%pntA%! leq !RU%pntR%! set /a "pntA+=1"&goto :UnionSch1
- if !AL%pntA%! leq !RU%pntR%! set "RU!pntR!=!AU%pntA%!"
- :UnionSch2
- if !BU%pntB%! leq !RU%pntR%! set /a "pntB+=1"&goto :UnionSch2
- if !BL%pntB%! leq !RU%pntR%! set "RU!pntR!=!BU%pntB%!"
-
- set "intersec=Y"
- if !AL%pntA%! gtr !BU%pntB%! (set "intersec=N") else (
- if !BL%pntB%! gtr !AU%pntA%! set "intersec=N")
- set /a "pntR+=1"
- (call :min !AL%pntA%! !BL%pntB%! RL!pntR!)
- if "!intersec!"=="Y" (call :max !AU%pntA%! !BU%pntB%! RU!pntR!) else (
- call :min !AU%pntA%! !BU%pntB%! RU!pntR!)
- goto :UnionLoop
- exit /b
-
-
-
- :copySet src dest
- call :clearSet %2
-
- set "i=0"
- :copySet.loop
- set /a i+=1
- for %%i in (%i%) do ( if "!%1L%%i!"=="" (exit /b) else (set %2L%%i=!%1L%%i!&set %2U%%i=!%1U%%i!) )
- goto :copySet.loop
-
- exit /b
-
- :min a b min (a,b 以串值调用, min 以变量名调用)
- if %1 lss %2 (set %3=%1) else (set %3=%2)
- exit /b
-
- :max a b max (a,b 以串值调用, max 以变量名调用)
- if %1 gtr %2 (set %3=%1) else (set %3=%2)
- exit /b
-
-
- :outputSet
- (set lastout=')
- set /p=%1={<nul
- if "!%1L1!"=="" echo }&exit /b
-
- set "i=0"
- :outputSet.loop
- set /a i+=1
- for %%i in (%i%) do (
-
- if "!%1L%%i!"=="" (if %%i neq 1 (echo }) else echo })&exit /b
- if "!%1L%%i!"=="!UOut!" (
- (if %%i neq 1 (echo }) else echo })&exit /b
- ) else if !%1L%%i! gtr !lastout! (
- if !%1L%%i! neq !%1U%%i! (
- set /p=[!%1L%%i!,!%1U%%i!],<nul
- ) else set /p=!%1L%%i!,<nul
- (set lastout=!%1U%%i!)
- )
-
- )
- goto :outputSet.loop
- exit /b
-
-
- :clearSet
- set "i=0"
- :clearSet.loop
- set /a i+=1
- for %%i in (%i%) do ( if "!%1L%%i!"=="" (exit /b) else (set %1L%%i=&set %1U%%i=) )
- goto :clearSet.loop
- exit /b
-
- :err
- echo 错误, 任意键退出&pause
- exit /b
-
- :getUniverseLU
- set "universeL=1"
- :get_uniLU
- set /a "universeL<<=1"
- if %universeL% lss 0 (set /a "universeU=-(universeL+1), universeL=0"&exit /b) else goto :get_uniLU
- exit /b
-
-
- :Simplify A 仅用于最后输出之前(不再做任何运算), 将相邻子集合并
- (call :copySet %1 A)&(set /a pntA=0, pntN=pntA+1)&set "AU0=!LOut!"
- :SimplifyLoop
- if "!AL%pntN%!"=="!UOut!" (call :copySet A %1)&exit /b
- set /a "tt=AL!pntN!-1"
- if "!AU%pntA%!" equ "!tt!" (
- set "AU!pntA!=!AU%pntN%!"
- set /a "pntN+=1"
- ) else set /a "pntA=pntN,pntN+=1"
- goto :SimplifyLoop
- exit /b
-
- :initSet
- set "%1=!%1: =!" & set "%1=!%1:{=!" & set "%1=!%1:}=!"
- set "pnt%1=0" & set "flag=CN"
- for %%i in (!%1!) do (
- set "tt=%%i"
- if "!tt:~0,1!"=="[" (
- if "!flag!" equ "L" (echo 集合%1语法错误:%%i&pause&goto :err)
- set "flag=L"
- set /a pnt%1+=1&set "%1L!pnt%1!=!tt:~1!"
- ) else if "!tt:~-1!"=="]" (
- if "!flag!" neq "L" (echo 集合%1语法错误:%%i&pause&goto :err)
- set "flag=R"
- set "%1U!pnt%1!=!tt:~0,-1!"
- ) else if "!flag!" equ "L" (echo 集合%1语法错误:%%i&pause&goto :err
- ) else set /a pnt%1+=1&set "%1L!pnt%1!=!tt!"&set "%1U!pnt%1!=!tt!"&set "flag=CN"
- )
- set /a pnt%1+=1&set "%1L!pnt%1!=!UOut!"&set "%1U!pnt%1!=!UOut!"
- exit /b
-
-
- :getSet
- (set lastout=')
- if "!%1L1!"=="" exit /b
-
- set "i=0"
- :getSet.loop
- set /a i+=1
- for %%i in (%i%) do (
- if "!%1L%%i!"=="" exit /b
- if "!%1L%%i!"=="!UOut!" (
- exit /b
- ) else if !%1L%%i! gtr !lastout! (
- echo !%1L%%i!~!%1U%%i!
- (set lastout=!%1U%%i!)
- )
- )
- goto :getSet.loop
-
- 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
复制代码
很是奇怪,当数字达到这些倍数的时候,用了上面几位的都没能得出结果呢
我的结果是- 236095488~236096511
- 244613120~244645887
- 455852032~455852287
- 455852544~455860223
- 989687808~989691903
- 992195584~992204799
- 1025248512~1025249023
- 1032587776~1032588543
- 1032816640~1032818687
- 1033001984~1033005055
- 1033013760~1033014015
- 1038834432~1038834687
- 1859217152~1859217407
- 1871978496~1871979519
- 1871997952~1871998463
- 1872057344~1872060415
- 1872098304~1872101375
- 1901395968~1901428735
- 1902616576~1902624767
- 1902844672~1902845951
- 1902854144~1902862335
- 1902869504~1902872575
- 1902873856~1902877439
- 1902878464~1902879231
- 1902880000~1902881791
- 1902882048~1902883583
- 1902886144~1902887679
- 1902887936~1902888959
- 1902892032~1902895615
- 1902896128~1902897919
- 1902898432~1902901247
- 1946530048~1946537983
- 1947236352~1947250687
- 1958889984~1958890239
- 1958932480~1958932735
- 2004402176~2004418559
- 2005696512~2005712895
- 2005839872~2005860351
- 2018951168~2018967551
- 2026173952~2026174463
- 2026175488~2026175743
- 2033398784~2033399807
- 2046873600~2046875647
- 2067817472~2067818495
- 2067886080~2067888127
- 2069377024~2069379071
- 2069473536~2069473791
- 2103140352~2103152639
- 2103173120~2103173375
- 2103173888~2103178495
- 2103178752~2103181311
- 2103371776~2103372031
- 2103372288~2103373823
- 2638074112~2638075391
- 3070885888~3070889983
- 3070915328~3070951423
- 3071852544~3071860223
- 3071860480~3071868927
- 3073949696~3073966079
- 3074066944~3074067455
- 3085560832~3085561855
- 3085593600~3085594111
- 3085863936~3085864447
- 3086007296~3086008319
- 3395876864~3395877887
- 3395941376~3395941887
- 3525758976~3525763071
- 3546327040~3546329087
- 3549161984~3549162495
- 3549617408~3549617663
- 3658432512~3658440703
- 3682828288~3682836479
- 3707358208~3707358463
- 3719067648~3719069439
- 3719523328~3719524351
- 3746106368~3746107391
- 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同一目录运行。- @if(0)==(0) echo off&dir /b *.txt|cscript -nologo -e:jscript "%~f0"&pause&exit /b&@end
-
- function compareInt(a, b){
- return parseInt(a) > parseInt(b);
- }
- function $bool(a){
- return !a || a=="undefined";
- }
- var fso = new ActiveXObject("Scripting.FileSystemObject");
- var files = WScript.StdIn.ReadAll().split("\r\n");
- for (var i=0; i<files.length; i++) {
- var fn=files[i];
- if(!fn) continue;
- WSH.Echo("处理文件:" + fn);
- var content = fso.OpenTextFile(fn,1).ReadAll()
- var begin,end,result="";
- content.replace(/(.*)(?:\r\n|$)/g, function($0,$1){
- var be=$1.split("~");
- if($bool(begin)) begin = be[0];
- if($bool(end)) end = be[1];
- if (be[0]-end-1>0) {
- result += begin + "~" +end + "\r\n";
- begin = be[0];
- }
- if(compareInt(be[1], end)) end = be[1];
- });
- result += begin + "~" +end;
- // WSH.Echo(result);
- fso.CreateTextFile(fn,2).Write(result);
- }
复制代码
作者: bailong360 时间: 2015-9-20 22:26
回复 8# kkfgef - @echo off
- for /f "delims=" %%i in ('dir /a-d /b *.txt') do (
- gawk "/^#<awk/,/^#>awk/{if(!/^#/)print}" %0|gawk -F "~" -f "-" "%%i">$
- move /y $ "%%i"
- )
- exit /b
- #<awk
- {if(NR==1){
- q[1]=$1;q[2]=$2
- } else {
- if($1<=q[2]+1){
- if($2>=q[2]) q[2]=$2
- } else {
- print q[1]"~"q[2]
- q[1]=$1;q[2]=$2
- }
- }
- }
- END{print q[1]"~"q[2]}
- #>awk
复制代码
需要第三方gawk支持
欢迎光临 批处理之家 (http://bathome.net./) |
Powered by Discuz! 7.2 |