awk的学习和使用(三)
上一篇 /
下一篇 2009-08-17 17:50:03
/ 个人分类:Linux
先看一篇文本,名为testfile,共6个字段:site、engine、url、num1、num2、num3
A.找出site、engine、url均相同的记录,将这些相同记录的num1,mum2、num3相加;
B.找到后三个值中为0的记录,将其赋值为NULL;
解题思路:
第一步:排序
第二部:求和
第三部:判断num为0的记录,做字符串替换
1.sort即可将其排序。注:sort testfile表示将文件中的每一行进行全排序,先从第一个字段排序,一直到最后一个字段;字段由第一个字母排序,直到最后一个字母;sort的分隔符指定参数为-t,由于本例是由第一个字段往后进行全排序,因此不需要额外指定分隔符;
2.比较前三个字段的值并求和,用awk。由于awk默认的分隔符为tab或者空格均视为分隔符,因此根据本文的特殊性(第一个字段中包含空格),需要单独指定分隔符为tab,打印第一个字段看看:
awk -F"\t" '{print $1}' 结果正确。
3.字符串替换.
3.1由于需要检查的字符串本身都是一个单独的字段(num1、num2、num3),因此可以使用awk字段判定:
if($4=="0")$4="NULL";
3.2另外可以使用awk的内部函数gsub来替换字符串:
gsub(/0/,"NULL");
这样子的结果会将每行中所有0都替换为NULL,实际我们只要求将tab后紧跟着的0替换为NULL,linux下tab可以用\<\>表示:
gsub(/\<0\>/,"NULL"); 表示将tab后面的0替换为NULL(这个解释非常奇怪,但是结果是对的。。有待考察)
3.3字符串替换功能,一般会使用比较简洁的sed 's/source-charactor/dest-charactor/'。其中的字符匹配支持正则表达式。
sed 's/\t0/\tNULL'
4.最后:
处理问题A的awk文件:testA.awk
BEGIN{FS="\t"} {if(NR==1) { site=$1;engin=$2;url=$3;n1=$4;n2=$5;n3=$6; } else if(site==$1&&engin==$2&&url==$3) { n1+=$4;n2+=$5;n3+=$6; } else { print(site"\t"engin"\t"url"\t"n1"\t"n2"\t"n3); site=$1;engin=$2;url=$3;n1=$4;n2=$5;n3=$6;} } END{print(site"\t"engin"\t"url"\t"n1"\t"n2"\t"n3)} |
处理问题B的awk文件:testB.awk
BEGIN{FS="\t"} { if($4=="0")$4="NULL"; if($5=="0")$5="NULL"; if($6=="0")$6="NULL"; print($1"\t"$2"\t"$3"\t"$4"\t"$5"\t"$6); } |
合并:
sort testfile | awk -f testA.awk | awk -f testB.awk > out |
收藏
举报
TAG: