linux列统计不同值操作的awk或shell脚本
在linux下面,用awk 或者shell等脚本如何实现下面的结果?
我有一个文件 file.txt ,大约1-2个G,共M行N列(M,N都大于100,对不同的文件M,N的值不同)
如何写一个脚本,统计每一列的列值一共有多少个不同值,把每个不同列值出现次数也统计出来,并对每列的列值按照统计结果进行降序排序
比如:
输入:
1,2,3,4,5,60
1,20,3,4,5,6
10,2,3,4,5,60
1,2,3,4,5,60
1,2,3,4,50,6
1,20,30,4,5,6
脚本输出结果为:
第1列:1,4次,10,1次
第2列:2,3次,20,2次
........
第6列:6,3次,60,3次
后来添加一列数据,结果忘了改。
应该改为这样:
脚本输出结果为:
第1列:1,5次,10,1次
第2列:2,4次,20,2次
........
第6列:6,3次,60,3次 展开
!#/bin/awk -f
BEGIN{
print "下面是文件对列的统计";
}
{
for(i=1;i<=NF;i++)
++a[i][$i];
}
END{
for(i=1;i<=NF;i++)
{
printf("第%s列",i);
for(j in a[i]) printf("\t%s,%s次",j,a[i][j]);
print "";
}
print "输出完毕";
}
将这个文件保存成一个文本文件,我这里举例文件名叫script,你要改成什么都可以
然后在命令行里敲
gawk -F"," -f /path/to/script /path/to/your/txt/file
比如你的test.txt和script文件都放在同一个文件夹/home/ha,那这个命令就是
gawk -F"," -f /home/ha/script /home/ha/test.txt
或者你也可以单敲一行命令
gawk -F"," 'BEGIN{ print "开始输出对列的统计"; } { for(i=1;i<=NF;i++) ++a[i][$i]; } END { for(i=1;i<=NF;i++) { printf("第%s列",i); for(j in a[i]) printf("\t%s,%s次",j,a[i][j]); print ""; } print "输出完毕"; }' test.txt
都是一样的,test.txt是你要统计的文件
这下面你的文件产生的输出
开始输出对列的统计
第1列 1,5次 10,1次
第2列 2,4次 20,2次
第3列 3,5次 30,1次
第4列 4,6次
第5列 5,5次 50,1次
第6列 6,3次 60,3次
输出完毕
awk有很多很多版本,这个脚本用gawk是可以的,其他的awk不一定。
思路我倒是明确,但我用的不是fawk,我这里完全不行啊。貌似普通的awk里面没有arr[i][j]的用法,就是普通的awk里面不支持二维数组。如果不支持二维数组,那该怎么才能实现呢?
对啊,普通awk确实没有二维数组
能不能装个gawk?主流的系统都会有啊,实在不能用的话可以考虑对每列单独进行处理。但是你的文件很大,列数也很多,会非常慢