[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

[文本处理] [已解决]批处理怎样对手机号码归属地数据进行筛选?

数据下载(更新了地址及quhao.txt)
http://www.rayfile.com/files/bd808cca-58db-11df-98b5-0015c55db73d/

说明:
1.第一个原始数据文件data.txt内含有20万条数据(中间以tab分隔),文件大小超过8MB
2.第二个quhao.txt文件有300多条数据(中间以空格分隔),文件大小不到5KB

==============================================================================
1.原始数据
手上有一个比较详尽的手机号码归属地数据文件data.txt,格式如下(中间以tab分隔)
1534960 宁夏银川 电信CDMA卡
1534961 宁夏银川 电信CDMA卡
1534967 宁夏银川 电信CDMA卡
1534968 宁夏银川 电信CDMA卡
1534969 宁夏银川 电信CDMA卡
1534970 青海西宁 电信CDMA卡
1534971 青海西宁 电信CDMA卡
1534972 青海西宁 电信CDMA卡
1534973 青海西宁 电信CDMA卡
1534974 青海西宁 电信CDMA卡
1534975 青海海东 电信CDMA卡
1534976 青海海东 电信CDMA卡
1534977 青海海西 电信CDMA卡
1534978 青海共和 电信CDMA卡
1534979 青海格尔木 电信CDMA卡
1534985 安徽巢湖 电信CDMA卡
1534986 安徽六安 电信CDMA卡
1534987 安徽六安 电信CDMA卡
多数为三段(多数号码是连续的,前后仅相差1,但部分号码不是连续的)

1566023 广东佛山 联通 GSM卡
1864353 吉林通化 联通WCDMA 3G卡
1881943 广东广州 移动TD-SCDMA 3G卡
1892413 广东广州 电信天翼  3G卡
部分数据为四段数据


2.数据精简
预将上述数据中,归属地相同的连续号码,精简为号段形式,并删掉手机卡类型,输出格式如下:
1534960 宁夏银川
1534962 未知
1534967 宁夏银川
1534970 青海西宁
1534975 青海海东
1534977 青海海西
1534978 青海共和
1534979 青海格尔木
1534980 未知
1534985 安徽巢湖
1534986 安徽六安

精简的目的就是极大地减小数据量,仅表示该号段第一个号码,所有大于第一个号码的均视为同一个归属地
解释为:1534960~1534961 宁夏银川,1534962~1534966 未知1534967~1534969 宁夏银川,1534970~1534974 青海西宁……

data.txt中多数号码是连续的,前后仅相差1
但部分不是连续的号码,应增加一行内容为“最后一个连续号码+1 空格 未知”,见增加的蓝色内容

如:1534961、1534963、1534967不是连续的,因此应增加“1534961+1 空格 未知”,即“1534962 未知
       若不加“1534962 未知”,则会误认为1534962与1534961归属相同




3.更改归属地名称为区号代码
另有一个quhao.txt文件,格式如下(中间以空格分隔)
111 未知
564 安徽六安
565 安徽巢湖
951 宁夏银川
971 青海西宁
972 青海海东
977 青海海西
979 青海格尔木

将刚才第二步精简后的数据中,参考quhao.txt,将对应的归属地名称改为区号代码,最终输出格式如下(中间以空格分隔)
1534960 951
1534962 111
1534967 951
1534970 971
1534975 972
1534977 977
1534978
1534979 979
1534980 111
1534985 565
1534986 564

quhao.txt中没有1534978对应的“青海共和”,所以后面为空(便于今后补充)


4.结果输出
如果最后结果文件大小不到5KB,显然把所有归属相同的都精简了,每个地区只剩一个号段了
最终结果文件大小应该超过600KB才合理


结果应该是这种格式(从小到大排列)
1300000 10
1300001 519
1300002 565
1300003 111
1300006 25
1300007 111
1300008 27
1300009 111
1300010 10
1300012 22
1300015 533
1300016 535
1300017 531
1300018 22
1300020 21
1300025 25
1300027 535
1300028 25
1300033 510
1300040 20
1300045 10

data20100506.rar 于 2010-5-6 14:48  更新
http://pan.baidu.com/share/link?shareid=4185092398&uk=1124163200
1

评分人数

    • Batcher: 感谢主动给标题标注[已解决]字样PB + 2

RE: 59

57楼代码稍作修改后, 可输出地区连续但号段不连续的断点, 输出结果去掉所有尾部的 空格111 后将与 CUer 的 gawk 版的结果完全一致:
  1. @echo off&setlocal enabledelayedexpansion
  2. sort data.txt /o data1.txt
  3. for /f "tokens=1-2" %%a in (quhao.txt) do set %%b=%%a
  4. ::\\取第一个电话号码
  5. set /p num=<data1.txt
  6. set /a num=num
  7. ::\\\\\\\
  8. (
  9. for /f "tokens=1-2" %%a in (data1.txt) do (
  10.   if !num! neq %%a (echo;!num! !未知!)&(set var=)
  11.   if "!var!" neq "%%b" (
  12.     echo;%%a !%%b!
  13.     set var=%%b
  14.   )  
  15.   set /a num=%%a+1
  16. )
  17. )>结果.txt
复制代码

TOP

回复59楼

这次代码运行没问题,结果也正确
尤其体现出gawk命令的速度优势

谢谢!!!

[ 本帖最后由 jack1505 于 2010-5-6 23:58 编辑 ]

TOP

  1. type data.txt | gawk -F"[ \t]" "(NR!=1)&&($1!=p1+1){print p1+1\" 未知\"}($1!=p1+1)||(p2!=$2){print $1,$2}{p1=$1;p2=$2}" >jingjian.txt
  2. gawk "NR==FNR{a[$2]=$1}NR>FNR{if($2 in a)print $1,a[$2];else print $1}" quhao.txt jingjian.txt >result.txt
复制代码
57楼得到的结果是50641行
我的代码得到和54楼得到的结果一样都是50679行

TOP

回复 57楼 的帖子

楼主不是说1534978后面应该为空么,但你的结果里面对应的是111。
我帮忙写的代码不需要付钱。如果一定要给,请在微信群或QQ群发给大家吧。
【微信公众号、微信群、QQ群】http://bbs.bathome.net/thread-3473-1-1.html
【支持批处理之家,加入VIP会员!】http://bbs.bathome.net/thread-67716-1-1.html

TOP

改成这样应该可以了
  1. @echo off&setlocal enabledelayedexpansion
  2. sort data.txt /o data1.txt
  3. for /f "tokens=1-2" %%a in (quhao.txt) do set %%b=%%a
  4. ::\\取第一个电话号码
  5. set /p num=<data1.txt
  6. set /a num=num
  7. ::\\\\\\\
  8. (
  9. for /f "tokens=1-2" %%a in (data1.txt) do (
  10.     if "!var!" neq "%%b" (
  11.         if !num! neq %%a echo;!num! !未知!
  12.         if #!%%b! equ # (echo;%%a !未知!) else echo;%%a !%%b!
  13.         set var=%%b
  14.     )
  15. set /a num=%%a+1
  16. )
  17. )>结果.txt
复制代码

[ 本帖最后由 netbenton 于 2010-5-6 21:38 编辑 ]

TOP

RE: 55

测试了下,结果最前面的几行为
1300000 10
1300000 111
1300001 519
1300000 111
1300002 565
1300000 111
1300006 25
1300000 111
1300008 27
1300000 111
1300010 10

与 LZ 在顶楼的要求是不符的:
1300000 10
1300001 519
1300002 565
1300003 111
1300006 25
1300007 111
1300008 27
1300009 111

TOP

1,如果号码不是连续的增加一个未知项
2,如果区域在quhao.txt中不存在,转为未知项
  1. @echo off&setlocal enabledelayedexpansion
  2. sort data.txt /o data1.txt
  3. for /f "tokens=1-2" %%a in (quhao.txt) do set %%b=%%a
  4. ::\\取第一个电话号码
  5. set /p num=<data1.txt
  6. set /a num=num
  7. ::\\\\\\\
  8. (
  9. for /f "tokens=1-2" %%a in (data1.txt) do (
  10.     if "!var!" neq "%%b" (
  11.         if !num! neq %%a echo; !num! !未知!
  12.         if #!%%b! equ # (echo;%%a !未知!) else echo;%%a !%%b!
  13.         set var=%%b
  14. ) else (set /a num=%%a+1)
  15. )
  16. )>结果.txt
复制代码

TOP

回复 53楼 的帖子

按照新要求重新写了代码
急就章之作请多做测试
因为不确定连续同一地区的多个号码段中是否存在未知号码段
所以对数据中的每个号码段都做了之前是否存在未知号码段的判定
因此代码运行时间增加为3倍左右
  1. @echo off & setlocal enabledelayedexpansion
  2. set t=%time%
  3. for /f "tokens=1,2" %%i in (quhao.txt) do set %%j=%%i
  4. set nextnum=1300000
  5. (for /f "tokens=1,2" %%i in (data.txt) do (
  6.     if %%i neq !nextnum! (
  7. echo !nextnum! 111
  8. set area=未知
  9. )
  10.     if not "%%j"=="!area!" (
  11.         echo %%i !%%j!
  12.         set area=%%j
  13.     )
  14. set /a nextnum=%%i+1
  15. ))>result.txt
  16. echo 起始时间:%t%
  17. echo 终止时间:%time%
  18. pause
  19. start result.txt
复制代码

[ 本帖最后由 qzwqzw 于 2010-5-6 18:47 编辑 ]
天的白色影子

TOP

回复52楼qzwqzw

感谢了,你的代码测试后,没问题
目前你和37楼的结果正确

42楼和46楼都增加了进度显示,确实速度大大降低
看来你的做法,加上起止的时间较为方便

不过我一楼补充了内容,这个没有实现,详见一楼第2条

[ 本帖最后由 jack1505 于 2010-5-6 18:11 编辑 ]

TOP

回复 42楼 的帖子

46楼的代码存在楼主所说的
一个地区一个号段的问题
算法与42楼存在本质的不同

42楼的代码有几个问题

setlocal的位置不知为何放在for之后
但是如果在命令行环境中执行此代码
将使cmd的当前会话产生大量临时变量
这显然违背了程序的设计原则

echo %%i %%j>con
应该是显示进度的
但正是它严重影响力程序的性能
去掉它运行速度可以提高十几倍
所以不如去掉
  1. @echo off & setlocal enabledelayedexpansion
  2. set t=%time%
  3. for /f "tokens=1,2" %%i in (quhao.txt) do set %%j=%%i
  4. (for /f "tokens=1,2" %%i in (data.txt) do (
  5.     if not "%%j"=="!address!" (
  6.         echo %%i !%%j!
  7.         set address=%%j
  8.     )
  9. ))>result.txt
  10. echo 起始时间:%t%
  11. echo 终止时间:%time%
  12. pause
  13. start result.txt
复制代码
天的白色影子

TOP

原帖由 随风 于 2010-5-6 14:29 发表
已帮楼主把数据上传到顶楼


谢谢版主,但是我把data.txt和quhao.txt更新了
可惜权限不够,无法编辑

TOP

回复 47楼 的帖子

已帮楼主把数据上传到顶楼
1

评分人数

技术问题请到论坛发帖求助!

TOP

原帖由 CUer 于 2010-5-6 09:56 发表
这跟你顶楼的描述不是冲突了吗?你的要求到底是怎样的呢?



谢谢一如既往的关注,我修改了顶楼的说明,这次应该能说明白

TOP

回复 45楼 的帖子

这跟你顶楼的描述不是冲突了吗?你的要求到底是怎样的呢?
应该将归属地相同连续号段进行精简
如1331000 至1331019都是上海,保留1331000即可
而往下1351210至1351219还是上海,同理保留1351210

TOP

返回列表