日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

發布時間:2025/4/9 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 用几条shell命令快速去重10G数据 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

  試想一下,如果有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 donefor 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命令還是很有必要的,這樣可以大大地降低你的工作量,提高工作的效率。這是我覺得相對較快的處理方式,如果您有更好的處理方式不妨告訴我。

轉載于:https://www.cnblogs.com/rwxwsblog/p/4586689.html

總結

以上是生活随笔為你收集整理的用几条shell命令快速去重10G数据的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。