Sed和awk一直是文本分析的神器,最近学习了陈皓的两篇博文,小试牛刀如下。
1. 背景
有些Map/Reduce数据产出之后,对于value数量不足的记录,要求在数据端予以补全。在这里,我们要求每条记录中有10个value,用逗号,“,”,进行分隔。
对于补全之后的结果,是不是可以保证每条记录中有10个value,我们需要进行验证。思路如下。
a) 从HDFS中导出数据为文本格式;
b) 使用awk和sed进行文本的分析;
c) 根据结果得出结论。
下面是分析的步骤。
2. 分析步骤
2.1 数据导出(略)
2.2 文本分析
原始的文本内容如下图。主要是看下文件的格式。原始内容过大,我们使用管道“|”和more命令防止输出内容过多。
图2.2.1 原始文本内容
在这里,第一列是key,第二列是对应的value。我们主要关心value的数量。提取value的值如下。主要是打印第二列的内容。
图2.2.2 提取value
下面可以得到每行的记录数量。在这里,我们使用FS重新定义了字段分隔符为“,”,使用NF获取一条记录中的列数,也就是value的个数。
图2.2.3 获取每行的value的数量
然后使用awk的统计功能,获取每个value数对应的记录数。如下图。我们使用了awk的数组功能进行统计,然后使用for循环将结果打印出来。
图2.2.4 获取统计结果。
为了使结果看起来更友好,我们对结果进行sort排序,记得使用“-n”参数,使其按照数字进行排序。另外,可以使用wc命令统计文件中的行数,即总记录数,如下图。
图2.2.5 最终结果
2.3 结论
根据上面的分析,我们得知文件中总记录为1101522,其中有10个value的记录数有1100253,占比99.8848%。这个结果是可以接受的。
当然我们这里的目的还是为了说明awk和sed的使用,下面是进一步的延伸。
2.4 更进一步
为了达到统计分析的目的,可以有多种方法。上面的只是一种,下面还有一种。
1)
awk '{print $2}' a.txt | awk 'BEGIN {FS=","} {print NF,"\t",$0 } ' | awk '{a[$1]++;} END {for (i in a) print i "\t" a[i];}' | sort –n
2)
awk '{print $2}' a.txt | sed 's/,/ /g' | awk '{a[NF]++} END {for (i in a) print i "\t" a[i];}' | sort –n
第一个就是我们上面分析时使用的方案。
第二个中,思路是使用sed将“,”替换为空格“ ”,使其可以更方便的被分析,直接使用NF即可。
另外,可以使用比较运算,找出特定个数的记录。
awk '{print $2}' a.txt | sed 's/,/ /g' | awk 'NF==10 {print $0}' | wc –l
通过修改不同的参数,结合wc命令,可以得到特定value数的记录数。这样也可以实现我们的目的。
本来还想使用split函数直接在第一步就将value部分进行分割,但是没成功;后面再试试。
3. 其它
上面的数据分析,在数据产出的时候也可以进行,直接使用hive进行统计。我们在这里仅用来作为awk和sed学习的一个示例。
4. 参考资料
Awk:《AWK 简明教程》
Sed:《sed 简明教程》