Shell脚本中利用awk处理大批量数据

一、需求

原始文件A为1.7G的文件,有5列,大约是1700万行的样子。另有2个辅助文件B和C,B、C文件均只有2列。A1和B1相同,A2和C1相同,要提取的数据列为A1、B2、C2、A4、A5,目标文件名为D.txt。

二、思路

2.1在使用awk处理数据之前,考虑使用whileread ……done<A.txt的方式来处理数据,但是执行效率太低,并不符合期望。

2.2后来使用awk处理数据,但是必须要解决的问题是传入外部数组或者是将三个文件的数据传入到awk中。

三、解决方式

3.1 使用while read ……done<A.txt的方式来处理数据

while read B1  B2

do

B_array[$B1]=$B2

done<B.txt

while read C1  C2

do

C_array[$C1]=$C2

done <B.txt

while read A1 A2 A3 A4 A5

do

B2_value=B_array[$A1]

C2_value=C_array[$A2]

echo$A1,$B2_value,$C2_value,$A3,$A4,$A5>>D.txt

fi

done <A.txt

#数据量少时可以使用第一种方式。

3.2 外部数组传入awk中

awk多文件处理,我遇到一个无法解决的问题,就是将3个文件读入到awk中就直接打印了,不可能执行其他的操作,于是我就放弃了这种方式而改用将外部数组传入到awk中的方式。于是我找到了以下代码

awk -vs1="${time[*]}" -v s2="${!time[*]}" ‘

BEGIN{split(s1,s3,"");split(s2,s4," ");

for(i=1;i<=length(s4);i++)

res[s4[i]]=s3[i];}‘

(参考博客:http://sunlujing.iteye.com/blog/1918907

最终处理数据的代码就变成了如下方式:

while readB1  B2

do

B_array[$B1]=$B2

done <B.txt

while readC1  C2

do

C_array[$C1]=$C2

done <B.txt

awk -F",", -v s1="${B_array[*]}" -v s2="${!B_array[*]}"-v w1="${C_array[*]}" -v w2="${!C_array[*]}" ‘

BEGIN{

split(s1,s3,",");

split(s2,s4,",");

for(i=1;i<=length(s4);i++)

B_new_array[s4[i]]=s3[i];

split(w1,w3,",");

split(w2,w4,",");

for(i=1;i<=length(w4);i++)

C_new_array[w4[i]]=w3[i];

}

{

len=split($1,A_array,"")

A1=A_array[1];

A2=A_array[2];

A3=A_array[3];

A4=A_array[4];

A5=A_array[5];

B2_value=B_new_array[A1];

C2_value=C_new_array[A2];

printA1,B2_value,C2_value,A3,A4,A5

}‘ A.txt>>D.txt

#执行时间大约是4分钟。

3.3 接着又出现了新的需求

新的需求是按照A1、B2、C2为分组,对A3、A4、A5分别求和操作。这要是在sql中就可以直接使用groupby 分组来执行了。

参考博客在此:http://linuxguest.blog.51cto.com/195664/424496(awk的类sql数据处理)

然后代码就变成了下面这样:

while readB1  B2

do

B_array[$B1]=$B2

done <B.txt

while readC1  C2

do

C_array[$C1]=$C2

done <B.txt

awk -F",", -v s1="${B_array[*]}" -v s2="${!B_array[*]}"-v w1="${C_array[*]}" -v w2="${!C_array[*]}" ‘

BEGIN{

split(s1,s3,",");

split(s2,s4,",");

for(i=1;i<=length(s4);i++)

B_new_array[s4[i]]=s3[i];

split(w1,w3,",");

split(w2,w4,",");

for(i=1;i<=length(w4);i++)

C_new_array[w4[i]]=w3[i];

}

{

len=split($1,A_array,"")

A1=A_array[1];

A2=A_array[2];

A3=A_array[3];

A4=A_array[4];

A5=A_array[5];

B2_value=B_new_array[A1];

C2_value=C_new_array[A2];

A3_array[A1","B2_value","C2_value]+=A3;

A4_array[A1","B2_value","C2_value]+=A4;

A5_array[A1","B2_value","C2_value]+=A5;}

END{

for( i inA3_array)

{

printi","A3_array[i]","A4_array","A5_array

}

}‘ A.txt>>E.txt

时间: 2024-10-13 17:40:36

Shell脚本中利用awk处理大批量数据的相关文章

让你提前认识软件开发(22):shell脚本中的文件操作

第1部分 重新认识C语言 shell脚本中的文件操作 [文章摘要] 编写shell脚本时,经常会涉及到对文件的操作,比如从文件中读取一行数据.向文件追加一行数据等.完成文件读写操作的方法有很多,了解各种命令下文件操作的执行情况,有助于开发人员在不同使用场景下选择合适的命令. 本文以实际的shell脚本为例,介绍了对文件进行操作的不同方法,为相关开发工作提供了参考. [关键词] shell  文件操作  读写  效率 一.概述 在某些软件项目的需求文档中,要求程序一次性读或写的数据规模较大,可达1

shell脚本介绍,shell脚本结构和执行方式,date命令的用法,shell脚本中的变量简介

笔记内容: 20.1 shell脚本介绍 20.2 shell脚本结构和执行 20.3 date命令用法 20.4 shell脚本中的变量 笔记日期:2017-11-21 20.1 shell脚本介绍 Shell Script,Shell脚本与Windows/Dos下的批处理相似,也就是用各类命令预先放入到一个文件中,方便一次性执行的一个程序文件,主要是方便管理员进行设置或者管理用的.但是它比Windows下的批处理更强大,比用其他编程程序编辑的程序效率更高,它使用了Linux/Unix下的命令

在shell脚本中进行条件控制以及使用循环

转载请标明:http://www.cnblogs.com/winifred-tang94/ if条件语句语法: if [ 条件表达式 ] then 代码 else 代码 fi 注意:在上面的if条件语句中,if和 [ 之间要有空格,而条件表达式和两边的 [ ] 都要有空格,条件表达式不能紧挨着 [ 和 ]. if条件表达式以fi结束. Eg. 结果出现了以下问题: 原因是因为开头在#!后还要有一个/,加上/后解释器错误没有了,代码如下: 可是仍然有没有那个文件或目录的错误.对于这个错误我觉得是e

shell脚本中的dat,计算器,内置变量的用法

什么是shell脚本.首先它是一个脚本,并不能作为正式的编程语言.因为是跑在linux的shell中,所以叫shell脚本.说白了,shell脚本就是一些命令的集合.举个例子,我想实现这样的操作: 1)进入到/tmp/目录: 2)列出当前目录中所有的文件名: 3)把所有当前的文件拷贝到/root/目录下: 4)删除当前目录下所有的文件. 简单的4步在shell窗口中需要你敲4次命令,按4次回车.这样是不是很麻烦?所以不妨把所有的操作都记录到一个文档中,然后去调用文档中的命令,这样一步操作就可以完

shell脚本中获取日期

数字时间转标准时间: 数字时间如:20151009163000 标准时间:2015-10-19 16:30:00 a=`head -1 /home/xxx/xxx/bin/.status |awk -F= '{print $2}'|sed -r 's/([0-9]{4})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})/\1-\2-\3 \4:\5:\6/'` 把标准时间转换成秒(据1970-1-1): date -d "$a" +%

[转]Shell脚本中获取SELECT结果值的方法

有时候我们可能会需要在Shell脚本中执行SELECT语句,并将结果赋值给一个变量,对于这样的情形,我们可以用以下的方法来达到目的. 点击(此处)折叠或打开 #!/bin/ksh # # Created : 2015.05.25 # Updated : 2015.05.25 # Author : Jet Chenxi Zhang # Description : Get SELECT result in Shell # Variable Definitions # ORACLE_SID=audte

shell脚本中重启tomcat进程

shell脚本 #! /bin/bash SHUTDOWN="/root/tomcat/bin/shutdown.sh" STARTTOMCAT="/root/tomcat/bin/startup.sh" echo "关闭tomcat" $SHUTDOWN ps -ef |grep tomcat |grep /root/platform |grep -v 'grep'|awk '{print $2}' | xargs kill -9 sleep

数组-在Shell脚本中的基本使用介绍

Shell脚本在运维工作中是极其重要的,而数组在shell脚本里的运用无论是在循环或运算方面都是非常实用的一个环节.下面是对shell脚本中数组方面一些操作在此进行记录,希望能帮助到有兴趣的朋友~ 1.数组定义 [[email protected] ~]# a=(1 2 3 4 5 6 7 8)[[email protected] ~]# echo $a1一对括号表示是数组,数组元素用“空格”符号分割开. 2.数组读取与赋值 1)得到长度:[[email protected] ~]# echo

Shell脚本中执行mysql的几种方式(转)

Shell脚本中执行mysql的几种方式(转) 对于自动化运维,诸如备份恢复之类的,DBA经常需要将SQL语句封装到shell脚本.本文描述了在Linux环境下mysql数据库中,shell脚本下调用sql语句的几种方法,供大家参考.对于脚本输出的结果美化,需要进一步完善和调整.以下为具体的示例及其方法. 1.将SQL语句直接嵌入到shell脚本文件中 复制代码 代码如下: --演示环境   [[email protected] ~]# more /etc/issue   CentOS rele