如何使用shell脚本快速排序和去重文件数据
前面写过一篇通过shell脚本去重10G数据的文章,见《用几条shell命令快速去重10G数据》。然而今天又碰到另外一个业务,业务复杂度比上次的单纯去重要复杂很多。找了很久没有找到相应的办法,于是用shell脚本程序去处理。具体业务逻辑:
1、首先根据给定指定进行排序
2、排序后对给定字段进行去重,去重的规则如下:
a)排序后如果相邻N行给定字段值相同的行数不超过两行,则两行都保留。
a)排序后如果相邻N行给定字段值相同的行数超过两行,则保留首行和尾行。
就这样一个业务逻辑,其实看起来并不是太难。但是问题来了,怎么才能在10~20G的数据中快速地进行处理呢?网上找了很久没找到相应的处理办法,于是先用一种相对笨的办法实现。
测试数据:
F250A4FFIDJDJ2938X39252E7,20080304041348 ,OQQQQB8,8769E,88888626,727218105,ss F250A4FFIDJDJ2938X39252E7,20080304041348 ,OQQQQB8,8769E,88888626,727218105,ss F250A4FFIDJDJ2938X39252E7,20080304041348 ,OQQQQB8,8769E,88888626,727218105,ss F250A4FFIDJDJ2938X39252E7,20080304041348 ,OQQQQB8,8769E,88888626,727218105,ss A0223EE1IDJDJ2938X39284BE,20080304041155 ,OQQQQ54,876F0,88888120,727271202,ss A0223EE1IDJDJ2938X39284BE,20080304041155 ,OQQQQ54,876F0,88888120,727271202,ss
shell脚本:
if [ "$#" != "2" ]; then echo "Usage: 参数1:文件路径,参数2:文件名。" exit fi #源文件所在目录 filepath=$1 #源文件绝对路径 orgfile=$filepath"/"$2 #合并字段后的临时文件 #mergerfile="$orgfile"_merge.txt #排序后的临时文件 sortfile="$orgfile"_sort.txt #最终结果文件 result_unique="$orgfile"_result_unique.txt echo "">$result_unique #echo "文件:$orgfile" #echo "开始合并字段..." #awk 'BEGIN{ FS=",";}{ print $1","$2","$3","$4","$5","$6","$7","$1$3$4 }' $orgfile > $mergerfile #echo "字段合并结束..." echo "文件排序 start..." #sort -t $"," -k 1,1 -k 9,9 $mergerfile >$sortfile sort -t $"," -k 1,2 $orgfile >$sortfile echo "文件排序 end..." printf "***********文件比较 start**************************\n" echo "while read line <$sortfile" cnt=0 #首行 firstline="" #尾行 lastline="" #上一次比较的key lastKey="" #文件行数 linecount=`sed -n '$=' $sortfile` i=1 echo "linecount=========>>>>>>>$linecount" while read line || [[ -n "$line" ]]; do echo $line; #合并需要比较的字段 compare=`echo "$line"|awk -F ',' '{print $1$3$4}'` echo "compare=====$compare" #判断字符串是否相等 if [ "$i" != "$linecount" -a "$lastKey" = "$compare" ];then echo "[ = ]" cnt=$(expr $cnt + 1) lastline="$line" else #首次进来 if [ "$firstline" = "" ];then firstline=$line cnt=1 #echo "$firstline" >> $result_unique fi #echo "----$i---------------->>>>>>>>>>>$cnt" if [ $cnt -gt 1 -o "$i" == "$linecount" ];then echo "----$i---------------->>>>>>>>>>>$cnt" if [ "$i" != "$linecount" -a "$lastline" != "" ];then echo "$lastline" >> $result_unique echo "$line" >> $result_unique fi # 最后一行的特殊处理 if [ "$i" == "$linecount" ];then echo "================last line===================" echo "$line" >> $result_unique fi firstline="$line" lastline="$line" cnt=1 elif [ $cnt -eq 1 ];then firstline=$line lastline="$line" cnt=1 echo "$lastline" >> $result_unique fi fi # 对比key lastKey="$compare" let i++ done <$sortfile echo "*******************文件 $orgfile 处理结束***************************" echo "*******************结果文件 $result_unique ***************************" exit
给脚本添加执行权限:
chmod +x uniquefile.sh
执行shell脚本
sh ./uniquefile.sh ./文件路径 文件名
结果:
[root@xddsdsdsddssd ~]# sh uniquefile.sh ./ testfile.csv 文件排序 start... 文件排序 end... ***********文件比较 start************************** while read line <.//testfile.csv_sort.txt linecount=========>>>>>>>6 A0223EE1IDJDJ2938X39284BE,20080304041155 ,OQQQQ54,876F0,88888120,727271202,ss compare=====A0223EE1IDJDJ2938X39284BEOQQQQ54876F0 A0223EE1IDJDJ2938X39284BE,20080304041155 ,OQQQQ54,876F0,88888120,727271202,ss compare=====A0223EE1IDJDJ2938X39284BEOQQQQ54876F0 [ = ] F250A4FFIDJDJ2938X39252E7,20080304041348 ,OQQQQB8,8769E,88888626,727218105,ss compare=====F250A4FFIDJDJ2938X39252E7OQQQQB88769E ----3---------------->>>>>>>>>>>2 F250A4FFIDJDJ2938X39252E7,20080304041348 ,OQQQQB8,8769E,88888626,727218105,ss compare=====F250A4FFIDJDJ2938X39252E7OQQQQB88769E [ = ] F250A4FFIDJDJ2938X39252E7,20080304041348 ,OQQQQB8,8769E,88888626,727218105,ss compare=====F250A4FFIDJDJ2938X39252E7OQQQQB88769E [ = ] F250A4FFIDJDJ2938X39252E7,20080304041348 ,OQQQQB8,8769E,88888626,727218105,ss compare=====F250A4FFIDJDJ2938X39252E7OQQQQB88769E ----6---------------->>>>>>>>>>>3 ================last line=================== *******************文件 .//testfile.csv 处理结束*************************** *******************结果文件 .//testfile.csv_result_unique.txt ***************************
最终结果文件:
[root@wewewwew ~]# more testfile.csv_result_unique.txt A0223EE1IDJDJ2938X39284BE,20080304041155 ,OQQQQ54,876F0,88888120,727271202,ss A0223EE1IDJDJ2938X39284BE,20080304041155 ,OQQQQ54,876F0,88888120,727271202,ss F250A4FFIDJDJ2938X39252E7,20080304041348 ,OQQQQB8,8769E,88888626,727218105,ss F250A4FFIDJDJ2938X39252E7,20080304041348 ,OQQQQB8,8769E,88888626,727218105,ss
时间比较赶,先这样实现吧。哪位亲们有好的办法请告诉我。
扫描公众号,关注更多信息
---------------------------------------------------------------------------------我是分割线--------------------------------------------------------------------------to be a better me, talk is cheap show me the code
版权所有,转载请注明原文链接。
文中有不妥或者错误的地方还望指出,以免误人子弟。如果觉得本文对你有所帮助不妨【推荐】一下!如果你有更好的建议,可以给我留言讨论,共同进步!
再次感谢您耐心的读完本篇文章。
----------------------------------------------------------------------------------------------------------------------------------------------------------------------
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
2015-07-03 ecshop设置一个子类对应多个父类并指定跳转url的修改方法