试想一下,如果有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=",",运行后的结果如下

vitest_menber.txt"内容""====================会员名:鬼脚七||||||||||||||||||会员等级:军长第5年|||姓名:张三 |||====================会员名:鬼脚七||||||||||||||||||会员等级:军长第5年|||姓名:张三 |||====================会员名:鬼脚七||||||||||||||||||会员等级:军长第5年|||姓名:张三 |||====================会员名:鬼脚七||||||||||||||||||会员等级:军长第5年|||姓名:张三 |||""====================会员名:鬼脚七||||||||||||||||||会员等级:军长第5年|||姓名:张三 |||====================会员名:鬼脚七||||||||||||||||||会员等级:军长第5年|||姓名:张三 |||====================会员名:鬼脚七||||||||||||||||||会员等级:军长第5年|||姓名:张三 |||====================会员名:鬼脚七||||||||||||||||||会员等级:军长第5年|||姓名:张三 |||""====================会员名:鬼脚七||||||||||||||||||会员等级:军长第5年|||姓名:张三 |||====================会员名:鬼脚七||||||||||||||||||会员等级:军长第5年|||姓名:张三 |||====================会员名:鬼脚七||||||||||||||||||会员等级:军长第5年|||姓名:张三 |||====================会员名:鬼脚七||||||||||||||||||会员等级:军长第5年|||姓名:张三 |||"

这里已经获取到了会员的信息;但是一行有多个会员的信息,而个数又是不固定的。因此下面是想办法一行显示一个会员

3、一行显示一个会员

由于会员信息间通过“====================”分割,要实现一行显示一个会员只需要将“====================”替换成换行即可。

sed -i "s/====================/

/g" test_menber.txt

查看test_menber.txt的内容

vitest_menber.txt1 "内容" 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]# moretest_uniq.txt 会员名:鬼脚七@@@@@@会员等级:军长第5年@姓名:张三 @内容

思路和测试完成了,但是文件比较多,一个个文件去处理也比较麻烦。因而写个脚本去处理即可

三、脚本批量处理

1、转换文件编码

[root@bogon yichen]# vi iconv_shell.sh#!/bin/shif [ "$#" != "2" ]; thenecho "Usage: `basename $0` dir filter"exitfiecho $1for file in `find $1 -name "$2"`; doecho "$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/shif [ "$#" != "2" ]; thenecho "Usage: `basename $0` dir filter"exitfifor file in `find $1 -name "$2"`; doecho "$file"awk 'BEGIN{ FS=",";}{ print $4 }' $file > ${file}_menberdone

调用

./awk_filler.sh ./ "*.txt_utf8"

此时生成的文件后缀为:.txt_utf8_menber

3、替换“====================”、“"”、“|||”和换行

vi sed_shell.sh#!/bin/shif [ "$#" != "2" ]; thenecho "Usage: `basename $0` dir filter"exitfifor file in `find $1 -name "$2"`; doecho "$file"sed -i "s/====================/

/g; s/"//g; /^$/d; s/|||/@/g" $filedonefor file in `find $1 -name "$2"`; doecho "$file"sed -i "/^$/d" $filedone

sed支持多表达式:sed "表达式1;表达式2" filename,注意表达式之间用“;”号隔开。

调用:

sh ./sed_shell.sh ./ "*.txt_utf8_menber"

替换后的文件后缀仍为txt_utf8_menber

4、去重

vi uniq_shell.sh#!/bin/shif [ "$#" != "2" ]; thenecho "Usage: `basename $0` dir filter"exitfifor file in `find $1 -name "$2"`; doecho "$file"sort -t $"@" -k 1,1 -su ${file} >${file}_uniqdone

调用:

sh ./uniq_shell.sh ./ "*.txt_utf8_menber"

最后生成去重后的文件后缀为txt_utf8_menber_uniq

其实也可以放在一个shell脚本里面完成,这里就不再阐述了。想想看10G的文件用几个简单的命令就完成了去重,可见linux的强大。所以说学几个简单的linux命令还是很有必要的,这样可以大大地降低你的工作量,提高工作的效率。这是我觉得相对较快的处理方式,如果您有更好的处理方式不妨告诉我。

c语言字符串去重用指针,用几条shell命令快速去重10G数据相关推荐

  1. C语言字符串相关一级指针内存模型

    C语言字符串相关一级指针内存模型 通过实例探索一级指针内存模型 通过实例探索一级指针内存模型 void main() {char buf[20]= "aaaa";char buf2 ...

  2. c语言 字符串和数组指针,C语言数组与指针一本道来

    数组与指针.png 指针的基础 注意本节内容可能在gcc下不能完成编译,请切换到Windows平台,使用dev-cpp或其他 指针本质上也是一个变量 指针要占用一定的内存空间(任何类型的指针的内存大小 ...

  3. java的字符串指针数组,C语言字符串中的指针与数组

    先说一下字符串字面量(字符串常量):双引号中的字符和编译器自动加入末尾的\0字符,都作为字符串储存在内存中.字符串常量属于静态存储类别,说明如果在函数中使用字符串常量,该字符串只会储存一次,在整个程序 ...

  4. C语言字符串去空格(最简单版本)

    #include<stdio.h>char* despace(char *a){int i=0;char *b=a;while(a[i++]!='\0'){if(a[i]==' '){fo ...

  5. c语言字符串 从后拷贝,C语言字符串拷贝

    C语言字符串拷贝利用指针操作,要清楚知道指针的指向 代码如下: #include #include #include char* my_strcpy1(char* dest, const char* ...

  6. 分割字符串c语言strsep,C语言 字符串切割

    #include #include #include /* 字符串切割函数 */ /* 知识补充: 1. 函数原型: char *strtok(char *str, const char *delim ...

  7. [Go语言入门] 07 Go语言字符串

    文章目录 07 Go语言字符串 7.1 字符串类型 7.2 Unicode & UTF-8 Unicode UTF-8 7.3 字符串字面量 7.4 字符串基本操作 返回字节数:使用函数len ...

  8. c语言字符串加减_C语言中指针的介绍

    C语言中指针的介绍 指针是C语言中广泛使用的一种数据类型. 运用指针编程是C语言最主要的风格之一.利用指针变量可以表示各种数据结构:能很方便地使用数组和字符串: 并能象汇编语言一样处理内存地址,从而编 ...

  9. c语言int转字符串_C语言零基础入门-指针-05

    C语言零基础入门-指针-05 本节要点: 1,字符指针. 2,字符串指针. 3,指针的参数传递 4,多重指针 01. 字符指针 这里的定义与前面的基本一样,所谓的字符指针就是这个指针指向的是一个字符型 ...

最新文章

  1. linux c 随机函数 rand srand 介绍
  2. 导出websphere内存镜像
  3. 【python图像处理】两幅图像的合成一幅图像(blending two images)
  4. ubuntu12.04LTS 安装eclipse和cdt
  5. 用angr解二进制题目1
  6. 使用“override”声明的成员函数不能重写基类成员_C++日志(三十五)虚基类与其子类的构造函数...
  7. java 隐藏了什么_JAVA程序中封装与隐藏是什么意思
  8. UILabel常用属性
  9. php符号%3c%3e啥意思,[PHP防火墙]输入内容存在危险字符,安全起见,已被本站拦截...
  10. java interceptor用法_java自定义拦截器用法实例
  11. onvif协议服务器端口,通过onvif协议接入海康、大华NVR步骤
  12. 《qos》一书受到读者好评
  13. python画棒棒糖程序_python之turtle简单绘制学习
  14. 连接黑屏_解决地下城与勇士PK服登录游戏卡在“正在连接服务器”的黑屏界面...
  15. 跟着AlphaGo 理解深度强化学习框架
  16. 账龄分析表excel模板_老会计分享财务报表及EXCEL会计报表分析系统模板!收藏领取!...
  17. sklearn做文本聚类分析
  18. Linux上安装rz、sz命令
  19. 文献翻译——基于关联规则挖掘识别的鸡源大肠杆菌共有多重耐药模式(上)
  20. Zotero及部分常用插件安装和使用教程

热门文章

  1. 计算机管理怎么分硬盘,电脑磁盘空间划分_电脑磁盘分区怎么分
  2. Linux系统的下载神器XDM
  3. WLAN与WiFi各是什么意思有什么区别
  4. MCS-51单片机指令系统--数据传送指令
  5. 25 个精美的手机网站模板
  6. GO语言环境搭建 + Sublime text 3 + Git + MarGo + gocode 组合配置详解
  7. 天猫,淘宝,京东收货信息中,自动识别手机号、姓名、省市区
  8. import 模块大小写问题
  9. java实现发送电子邀请函_电子邀请函的发展会怎样?
  10. 使用JavaCV把图片合成视频(实用)