用几条shell命令快速去重10G数据

来源:互联网 发布:mac调整输入法顺序 编辑:程序博客网 时间:2024/05/22 11:50
试想一下,如果有10G数据,或者更多;怎么才能够快速地去重呢?你会说将数据导入到数据库(mysql等)进行去重,或者用java写个程序进行去重,或者用Hadoop进行处理。如果是大量的数据要写入数据库也不是一件容易的事情,首先你需要开发一个程序将数据写入数据库,然后再用数据库的select distinct或者group by进行去重。如果是一次性的工作,这种方式显得就比较笨拙了。那么有没有更好的办法呢?下面记录一下我是怎么从10G数据里面迅速去重的。这里采用shell脚本的方式进行处理。如果您对shell脚本不熟悉,可以参考之前的文章我常用的那些linux命令,里面介绍了我常用的一些linux命令。也可以查看本博客的linux分类http://www.cnblogs.com/rwxwsblog/category/687866.html,基本上就是里面说到的一些知识点。好了,入正题。   一、说明:   1、这10G数据分布在七八个文件中   2、文件编码格式为gb2312   3、数据格式: 复制代码 "ID","已采","已发","内容","PageUrl" "1","1","1","====================会员名:鬼脚七||||||||||||||||||会员等级:军长第5年|||姓名:张三 |||====================会员名:鬼脚七||||||||||||||||||会员等级:军长第5年|||姓名:张三 |||====================会员名:鬼脚七||||||||||||||||||会员等级:军长第5年|||姓名:张三 |||====================会员名:鬼脚七||||||||||||||||||会员等级:军长第5年|||姓名:张三 |||","http://www.xxx.com/" "1","1","1","====================会员名:鬼脚七||||||||||||||||||会员等级:军长第5年|||姓名:张三 |||====================会员名:鬼脚七||||||||||||||||||会员等级:军长第5年|||姓名:张三 |||====================会员名:鬼脚七||||||||||||||||||会员等级:军长第5年|||姓名:张三 |||====================会员名:鬼脚七||||||||||||||||||会员等级:军长第5年|||姓名:张三 |||","http://www.xxx.com/" "1","1","1","====================会员名:鬼脚七||||||||||||||||||会员等级:军长第5年|||姓名:张三 |||====================会员名:鬼脚七||||||||||||||||||会员等级:军长第5年|||姓名:张三 |||====================会员名:鬼脚七||||||||||||||||||会员等级:军长第5年|||姓名:张三 |||====================会员名:鬼脚七||||||||||||||||||会员等级:军长第5年|||姓名:张三 |||","http://www.xxx.com/" 复制代码     数据格式说明: 上面是3行数据每行都是5个field 每个field间用“,”隔开而需要的内容在第4个field(也就是内容这个field)内容field间会员用“====================”隔开  要达到的效果:将会员信息提取出来并去重   二、实现思路和测试:   1、由于文件编码是gb2312编码,所以第一步是将文件编码转成utf-8编码 iconv -c -f gb2312 -t utf-8 test.txt > test2.txt   这里我们用linux系统自带的iconv命令进行转换,-c的意思是将无法识别的字符直接忽略掉   2、获取会员信息,由于是第4个field,因而我们只需要获取第四个field即可,这里采用awk命令获取 awk 'BEGIN{ FS=",";}{ print $4 }' test2.txt > test_menber.txt   awk指定分隔符的方法为FS=",",运行后的结果如下 复制代码 vi test_menber.txt "内容" "====================会员名:鬼脚七||||||||||||||||||会员等级:军长第5年|||姓名:张三 |||====================会员名:鬼脚七||||||||||||||||||会员等级:军长第5年|||姓名:张三 |||====================会员名:鬼脚七||||||||||||||||||会员等级:军长第5年|||姓名:张三 |||====================会员名:鬼脚七||||||||||||||||||会员等级:军长第5年|||姓名:张三 |||" "====================会员名:鬼脚七||||||||||||||||||会员等级:军长第5年|||姓名:张三 |||====================会员名:鬼脚七||||||||||||||||||会员等级:军长第5年|||姓名:张三 |||====================会员名:鬼脚七||||||||||||||||||会员等级:军长第5年|||姓名:张三 |||====================会员名:鬼脚七||||||||||||||||||会员等级:军长第5年|||姓名:张三 |||" "====================会员名:鬼脚七||||||||||||||||||会员等级:军长第5年|||姓名:张三 |||====================会员名:鬼脚七||||||||||||||||||会员等级:军长第5年|||姓名:张三 |||====================会员名:鬼脚七||||||||||||||||||会员等级:军长第5年|||姓名:张三 |||====================会员名:鬼脚七||||||||||||||||||会员等级:军长第5年|||姓名:张三 |||" 复制代码  这里已经获取到了会员的信息;但是一行有多个会员的信息,而个数又是不固定的。因此下面是想办法一行显示一个会员   3、一行显示一个会员   由于会员信息间通过“====================”分割,要实现一行显示一个会员只需要将“====================”替换成换行即可。 sed -i "s/====================/\n/g" test_menber.txt   查看test_menber.txt的内容 复制代码 vi test_menber.txt 1 "内容" 2 " 3 会员名:鬼脚七||||||||||||||||||会员等级:军长第5年|||姓名:张三 ||| 4 会员名:鬼脚七||||||||||||||||||会员等级:军长第5年|||姓名:张三 ||| 5 会员名:鬼脚七||||||||||||||||||会员等级:军长第5年|||姓名:张三 ||| 6 会员名:鬼脚七||||||||||||||||||会员等级:军长第5年|||姓名:张三 |||" 7 " 8 会员名:鬼脚七||||||||||||||||||会员等级:军长第5年|||姓名:张三 ||| 9 会员名:鬼脚七||||||||||||||||||会员等级:军长第5年|||姓名:张三 ||| 10 会员名:鬼脚七||||||||||||||||||会员等级:军长第5年|||姓名:张三 ||| 11 会员名:鬼脚七||||||||||||||||||会员等级:军长第5年|||姓名:张三 |||" 12 " 13 会员名:鬼脚七||||||||||||||||||会员等级:军长第5年|||姓名:张三 ||| 14 会员名:鬼脚七||||||||||||||||||会员等级:军长第5年|||姓名:张三 ||| 15 会员名:鬼脚七||||||||||||||||||会员等级:军长第5年|||姓名:张三 ||| 16 会员名:鬼脚七||||||||||||||||||会员等级:军长第5年|||姓名:张三 |||" 复制代码     4、替换掉其他字符“"”、空行和“|||” #将“"”替换成空字符串 sed -i "s/\"//g" test_menber.txt #删除空行 sed -i '/^$/d' test_menber.txt #将分隔符|||换成@ sed -i "s/|||/@/g" test_menber.txt      5、根据会员名去重 sort -t $"@" -k 1,1 -su test_menber.txt >test_uniq.txt   -t可以指定分隔符,-k指定排序的field, -su表示稳定排序并去重   查看结果 [root@bogon yichen]# more test_uniq.txt 会员名:鬼脚七@@@@@@会员等级:军长第5年@姓名:张三 @ 内容  思路和测试完成了,但是文件比较多,一个个文件去处理也比较麻烦。因而写个脚本去处理即可   三、脚本批量处理   1、转换文件编码 复制代码 [root@bogon yichen]# vi iconv_shell.sh #!/bin/sh if [ "$#" != "2" ]; then echo "Usage: `basename $0` dir filter" exit fi echo $1 for file in `find $1 -name "$2"`; do echo "$file" iconv -c -f gb2312 -t utf8 $file > ${file}_utf8 复制代码  调用./iconv_shell.sh 目录 文件通配符,例如: ./iconv_shell.sh ./ "*txt"   此时生成的文件后缀为:.txt_utf8   2、提取会员信息 复制代码 vi awk_filler.sh #!/bin/sh if [ "$#" != "2" ]; then echo "Usage: `basename $0` dir filter" exit fi for file in `find $1 -name "$2"`; do echo "$file" awk 'BEGIN{ FS=",";}{ print $4 }' $file > ${file}_menber done 复制代码  调用 ./awk_filler.sh ./ "*.txt_utf8"   此时生成的文件后缀为:.txt_utf8_menber   3、替换“====================”、“"”、“|||”和换行 复制代码 vi sed_shell.sh #!/bin/sh if [ "$#" != "2" ]; then echo "Usage: `basename $0` dir filter" exit fi for file in `find $1 -name "$2"`; do echo "$file" sed -i "s/====================/\n/g; s/\"//g; /^$/d; s/|||/@/g" $file done for file in `find $1 -name "$2"`; do echo "$file" sed -i "/^$/d" $file done 复制代码  sed支持多表达式:sed "表达式1;表达式2" filename,注意表达式之间用“;”号隔开。   调用: sh ./sed_shell.sh ./ "*.txt_utf8_menber"   替换后的文件后缀仍为txt_utf8_menber   4、去重 复制代码 vi uniq_shell.sh #!/bin/sh if [ "$#" != "2" ]; then echo "Usage: `basename $0` dir filter" exit fi for file in `find $1 -name "$2"`; do echo "$file" sort -t $"@" -k 1,1 -su ${file} >${file}_uniq done 复制代码  调用: sh ./uniq_shell.sh ./ "*.txt_utf8_menber"   最后生成去重后的文件后缀为txt_utf8_menber_uniq   其实也可以放在一个shell脚本里面完成,这里就不再阐述了。想想看10G的文件用几个简单的命令就完成了去重,可见linux的强大。所以说学几个简单的linux命令还是很有必要的,这样可以大大地降低你的工作量,提高工作的效率。这是我觉得相对较快的处理方式,如果您有更好的处理方式不妨告诉我。 ---------------------------------------------------------------------------------我是分割线-------------------------------------------------------------------------- to be a better me, talk is cheap show me the code 版权所有,转载请注明原文链接。 文中有不妥或者错误的地方还望指出,以免误人子弟。如果觉得本文对你有所帮助不妨【推荐】一下!如果你有更好的建议,可以给我留言讨论,共同进步! 再次感谢您耐心的读完本篇文章。 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 肺部化疗恶心反胃怎么办吃什么药好 好久没运动一运动全身酸痛怎么办 怀孕两个月了一直吐没体力怎么办 公务员审查六级口语证丢了怎么办 农资经营如果被执法查处了怎么办? 干隧道测量坚持不下去该怎么办 老家房子强拆没钱做没钱补怎么办? 魔兽世界出了两个一样的传说怎么办 死亡事故后遇上不讲理家属怎么办 死亡事故后死亡者家属不讲理怎么办 住的地方治安乱混混多怎么办 使命召唤进去感觉动作好慢怎么办 40岁后不够硬不持久怎么办 如果别人毁灭了你的梦想怎么办 如果死者托梦说自己过的不好怎么办 吵架了老婆跑回娘家不回家了怎么办 和老婆吵架她跑回娘家了怎么办 鞋子里面的皮穿的都是泥怎么办 绝地求生手游模拟器键位不灵怎么办 我更新目录的时候目录不存在怎么办 如果别人欠我钱不还 我该怎么办 老婆欠信用卡的钱我该怎么办 我欠了很多钱我该怎么办 一个人欠我钱跑了我该怎么办 买房子时间长了成危楼了怎么办 别人欠我钱人找不到了怎么办 欠银行信用卡钱人失踪了怎么办 欧洲卡车模拟2没油了怎么办 蓝牙安装包里没有微信怎么办 腾讯手游模拟器玩全军出击卡怎么办 手游cf用模拟器画面很抖怎么办 腾讯手游助手模拟器游戏卡死怎么办 腾讯手游模拟器提示注册以满怎么办 手游绝地求生被检测成模拟器怎么办 腾讯手游助手模拟器内存不够怎么办 微信视频对方听不到我的声音怎么办 学生考试传纸条作弊老师应怎么办 苹果手机微信小游戏没有声音怎么办 红米手机游戏下好了安装不了怎么办 小米手机sd卡存储已满怎么办 英雄联盟峡谷之巅资格被收回怎么办