标题: [文本处理] 批处理按照手机号段整理手机号码数据库 [打印本页]
作者: namejm 时间: 2009-2-13 16:15 标题: 批处理按照手机号段整理手机号码数据库
在其他论坛看到了一个按照手机号段整理收集号码数据库的求助帖,觉得这个题目很有挑战性,并且也很实用,特发出来让大家练练手。
提示:整理出来的数据共有5670行,生成的文件大小至少129K,占用空间132K。
以下是那位楼主的原帖,原始格式数据请下载附件。
有一个文本为139.txt,部分内容如下:
省份 | 城市 | 城市区号 | 1390 | 1391 | 1392 |
上海 | 上海 | 21 | 160-162 | 600-899 | 空 |
云南 | 临沧 | 883 | 883,921 | 空 | 700-701,703,830-839 |
云南 | 丽江 | 888 | 888 | 空 | 704,880-889 |
云南 | 保山 | 875 | 875 | 空 | 705,750-759 |
云南 | 楚雄 | 878 | 878 | 空 | 707-708,780-789 |
云南 | 版纳 | 691 | 881 | 空 | 810-819 |
云南 | 玉溪 | 877 | 877,889 | 空 | 770-779,840-849 |
云南 | 红河 | 873 | 873 | 空 | 730-739,800-809 |
云南 | 迪庆 | 887 | 空 | 空 | 870-879 |
内蒙古 | 临河 | 478 | 478 | 空 | 空 |
内蒙古 | 乌兰浩特 | 482 | 空 | 空 | 空 |
内蒙古 | 乌海 | 473 | 473 | 空 | 空 |
内蒙古 | 包头 | 472 | 472 | 空 | 空 |
先解释一下,这个文本是139手机号段(前七位)的数据库,比如第一行的1390,指的是手机号的前四位,下面的160-199,指的是1390160~1390199之间的所有号段;再下面的883,921指的是两个号段,如1390883和1390921;空白的地方表示没有号段(已经替换为“空”),每个方格都以Tab键隔开。
需求:导出所有的号段,格式为"手机号段,省份,城市,城市区号"
例如:
1390160,上海,上海,21
1390161,上海,上海,21
1390162,上海,上海,21
1390883,云南,临沧,883
1390921,云南,临沧,883
。。。。。。。。。。
这只是139号段的一部分内容,并且还有很多其它号段的文本,但排列都是一样。自己考虑了很久,都不能实现,请问大家有没有什么好办法?
补充说明一下:仔细观察txt文件,可以发现,同一行上的数据组成情况是非常复杂的:有的是3位,有的是4位,有的是以短横线连接的连续数字,
有的数字还是以0打头的,处理的时候要特别小心。
作者: lockmove 时间: 2009-2-13 21:38
给出的txt实在是太乱了.哪个对其哪个.不知道bat能不能对excel操作
作者: namejm 时间: 2009-2-13 22:08
贴在表格中的数据复制到本地后,是比较乱,那是因为论坛会对一些空格做处理,而附件中的原始数据都是以跳格键来分隔的,不要受到视觉上的影响,直接数跳格键的个数、或者打开里面的excel文档来看就能知道数据的规律了。
这个例子非常具有实用性,并且颇有挑战性:如何处理连续的跳格键、如何用代码确定哪列数据对应哪个位置、如何在连续和断开的数字中罗列所有的数值等等,都是非常考验人的。如果找对了方案,将会比较容易;如果没想到好方法,则会无从下手。暂时不提供代码,看看有谁能很好地解决它。
作者: Batcher 时间: 2009-2-13 23:32 标题: 回复 2楼 的帖子
BAT只能胜任简单的excel处理,稍微复杂点的可以使用VBS来解决。
作者: 随风 时间: 2009-2-14 04:45
- @echo off&setlocal enabledelayedexpansion
- ::因论坛无法处理tab跳格,
- ::测试时将代码中的 set "tab=#" 中的#号改为tab键即可。。
- ::注意事项:
- ::需处理的号码出现 多少号至多少号时
- ::如 160-162 这种情况下“-”号左右的数字位数必须是一样的
- :: 象 198-1234 这样的就会出错。
-
- set "wj1=a.txt"
- set "wj2=b.txt"
-
- set "tab=#"
-
- if "%tab%"=="#" (
- echo.&echo 请先将代码中的 set "tab=#" 中的#号改为tab键
- echo.&pause>nul&exit
- )
-
- set t=%time%
- echo.1>nul 3>"%wj2%"
- set /p var=<"a.txt"
- for /l %%a in (1 1 3) do set "var=!var:*%tab%=!"
- set "var=!var:%tab%= !"
- for /f "usebackq skip=1 delims=" %%i in ("%wj1%") do (
- for /f "tokens=1-3* delims=%tab%" %%a in ("%%i") do (
- set "sen=%%a"
- set "cen=%%b"
- set "quhao=%%c"
- )
- set str=%%i
- for /l %%a in (1 1 3) do set "str=!str:*%tab%=!"
- for %%z in (%var%) do (
- if not "!str:~0,1!"=="%tab%" (
- for /f "tokens=1 delims=%tab%" %%E in ("!str!") do (
- for %%f in (%%E) do (
- set "num=%%f"
- set "num2=!num:-=!"
- if "!num2!"=="!num!" (set x=1!num! 1 1!num!) else (
- set "x=1!num:-= 1 1!"
- )
- for /l %%L in (!x!) do (
- set num3=%%L&set "num3=!num3:~1!"
- echo %%z!num3! !sen! !cen! !quhao!
- ))))
- set "str=!str:*%tab%=!"
- ))
-
- echo.1>nul 4>con
- echo %t%
- echo %time%
- call :time0 "%t%" "%time%" ok
- echo %ok%
- pause
- start "" notepad "%wj2%"
- exit
-
- :time0 计算批处理运行时间 (封装)
- @echo off&setlocal&set /a n=0&rem code 随风 @bbs.bathome.net
- for /f "tokens=1-8 delims=.: " %%a in ("%~1:%~2") do (
- set /a n+=10%%a%%100*360000+10%%b%%100*6000+10%%c%%100*100+10%%d%%100
- set /a n-=10%%e%%100*360000+10%%f%%100*6000+10%%g%%100*100+10%%h%%100)
- set /a s=n/360000,n=n%%360000,f=n/6000,n=n%%6000,m=n/100,n=n%%100
- set "ok=%s% 小时 %f% 分钟 %m% 秒 %n% 毫秒"
- endlocal&set "%~3=%ok:-=%"&goto :EOF
复制代码
[ 本帖最后由 随风 于 2009-2-14 05:12 编辑 ]
作者: batman 时间: 2009-2-14 09:54
有大的错误,所以编辑掉。。。
[ 本帖最后由 batman 于 2009-2-14 12:34 编辑 ]
作者: namejm 时间: 2009-2-14 09:57
随风的代码执行效率非常高,处理顶楼的文件在我的机器上只需要1秒多时间,这恐怕是最快的代码了。
我也写了一个,效率比随风的慢多了,在我的机器上需要8秒左右的时间,但是,作为不同的解题思路,我还是献丑把代码发出来——再次对随风的代码表示赞叹:牛人不常有,今年特别多!- @echo off
- :: 请把TAB字符替换为跳格键
- echo.1>nul 3>1.txt
- setlocal enabledelayedexpansion
- for /f "skip=1 delims=" %%i in (139.txt) do (
- set "str=%%i"
- set "str=!str:TAB=#TAB!"
- set "str=!str:,=,!"
- set num=-4
- for %%j in (!str!) do (
- set /a num+=1
- if !num! lss 0 (
- set address=%%j
- set address=!address:#=!
- set address!num!=!address!
- ) else call :next %%j
- )
- )
- echo.1>nul 4>con
- echo %time%
- start notepad.exe 1.txt
- pause
- exit
-
- :next
- set str=%1
- set str=%str:,=,%
- set str=%str:#=%
- for %%i in (%str%) do (
- set var1=%%i
- set var2=!var1:=-!
- if "!var1!"=="!var2!" (
- set var=1!var1!,1,1!var1!
- ) else set var=1!var1:-=,1,1!
- for /l %%i in (!var!) do (
- set str=%%i
- echo 139%num%!str:~1! %address-3% %address-2% %address-1%
- )
- )
- goto :eof
复制代码
作者: 随风 时间: 2009-2-14 10:38
呵呵,过奖过奖,^_^
有了 echo.1>nul 3>1.txt
就不需要 cd.>1.txt 了
作者: terse 时间: 2009-2-14 10:46
贴下我的 凑个热闹- @echo off&setlocal enabledelayedexpansion
- set "Tab=#"
- if "%Tab%"=="#" (
- echo.&echo 请先将代码中的 set "Tab=#" 中的#号改为Tab键
- echo.&pause>nul&exit
- )
- set/p str=<139.txt
- echo.1>nul 3>139_new.txt
- for /f "tokens=3* delims=%Tab%" %%i in ("%str%") do set str=%%j
- for %%i in (%str%) do set/a n+=1&set _!n!=%%i
- for /f "skip=1 tokens=1-3* delims=%Tab%" %%i in (139.txt) do (
- set "str=%%i%Tab%%%j%Tab%%%k"
- set "var=%%l"
- set "str1="&set "m="
- set var=!var:%Tab%=%Tab%#!
- call:next "!var!"
- if not defined str1 echo;%Tab%!str!
- )
- echo.1>nul 4>con
- start notepad "139_new.txt"&exit
- :next
- for /f "tokens=1* delims=%Tab%" %%i in (%1) do (
- set/a m+=1
- for %%a in (%%i) do (
- if not "%%a"=="#" (
- set str1=%%a
- set str1=!str1:#=!
- set str2=!str1:*-=!
- call set str1=%%str1:-!str2!=%%
- for /l %%b in (1!str1! 1 1!str2!) do (
- set b=%%b
- if %%b lss 10000 (set b=!b:~-3!) else set b=!b:~-4!
- call echo;%%_!m!%%!b!%Tab%!str!
- )))
- if not "%%j"=="" call :next "%%j"
- )
-
复制代码
[ 本帖最后由 terse 于 2009-2-14 10:58 编辑 ]
作者: namejm 时间: 2009-2-14 10:48
原帖由 随风 于 2009-2-14 10:38 发表
呵呵,过奖过奖,^_^
有了 echo.1>nul 3>1.txt
就不需要 cd.>1.txt 了
确实是不再需要cd.>1.txt了,呵呵,测试的收尾工作没做彻底。
作者: 随风 时间: 2009-2-14 10:51
terse 的代码提示信息中好像少了个反括弧吧
你的代码有误,无法运行,是否发帖时错删了内容??
真是奇怪了,运行jm的代码,1.txt 中没有内容??
[ 本帖最后由 随风 于 2009-2-14 10:58 编辑 ]
作者: terse 时间: 2009-2-14 10:59
原帖由 随风 于 2009-2-14 10:51 发表
terse 的代码提示信息中好像少了个反括弧吧
你的代码有误,无法运行,是否发帖时错删了内容??
确实是! 谢随风兄
另随风兄的代码如能应对不定列 就更完美了
[ 本帖最后由 terse 于 2009-2-14 11:00 编辑 ]
作者: 随风 时间: 2009-2-14 11:05
原帖由 terse 于 2009-2-14 10:59 发表
确实是! 谢随风兄
另随风兄的代码如能应对不定列 就更完美了
能说详细点吗?
我的代码应该是不受 列数 限制的啊。。?
[ 本帖最后由 随风 于 2009-2-14 11:08 编辑 ]
作者: batman 时间: 2009-2-14 11:09
我6楼的还是有点问题,这个应该还可以了:- @echo off&setlocal enabledelayedexpansion
- echo 139号段[tab]省份[tab]城市[tab]城市区号>num.xls
- for /f "delims=" %%a in (139.txt) do (
- set /a n=-4&set "code="
- set "str=%%a"&set "str=!str:,=#!"
- for %%b in (!str!) do (
- set /a n+=1
- if !n! lss 0 (
- set "code=!code![tab]%%b"
- ) else (
- if "%%b" neq "无" (
- set "var=%%b"&set "var=!var:#= !"
- for %%c in (!var!) do (
- set "string=%%c"&set "k="
- if "!string:-=!" neq "!string!" (
- for /f "tokens=1,2 delims=-" %%d in ("%%c") do (
- set "a=%%d"&set "b=%%e"
- if "!a:~,1!" equ "0" set "a=1!a!"&set "k=0"
- if "!b:~,1!" equ "0" set "b=1!b!"
- for /l %%f in (!a!,1,!b!) do (
- set "c=%%f"
- if defined k set "c=!c:~1!"
- echo 139!n!!c![tab]!code:~1!>>num.xls
- )
- )
- ) else (
- echo 139!n!%%c[tab]!code:~1!>>num.xls
- )
- )
- )
- )
- )
- )
- start num.xls
复制代码
作者: namejm 时间: 2009-2-14 11:20
原帖由 随风 于 2009-2-14 10:51 发表
真是奇怪了,运行jm的代码,1.txt 中没有内容??
更新代码的时候,漏打了两个字符,现在已经改过来了。
作者: terse 时间: 2009-2-14 11:20
原帖由 随风 于 2009-2-14 11:05 发表
能说详细点吗?
我的代码应该是不受 列数 限制的啊。。?
我测试的是附件里的文本
作者: 随风 时间: 2009-2-14 11:30 标题: 回复 16楼 的帖子
我测试了你提供的附件,没什么问题啊?
作者: terse 时间: 2009-2-14 11:57
原帖由 随风 于 2009-2-14 11:30 发表
我测试了你提供的附件,没什么问题啊?
是我混淆了 我这边错的
欢迎光临 批处理之家 (http://bbs.bathome.net/) |
Powered by Discuz! 7.2 |