1

我有一个如下所示的数据集:

项目 1 20 30 12项目
1 10 50 17
项目 2 -9 112 15
项目 2 -9 100 10

实际数据集有 101 列。我想打印每列中连续值的平均值(包含名称的第一列除外)。

所以预期的输出是

项目1 15 40 14.5
项目 2 -9 106 12.5

我从这个链接中发现,我可以使用以下代码对单个列执行此操作

awk '{sum+=$2}(NR%2)==0{print sum/2; sum=0;}'

但我无法弄清楚如何对其余列执行此操作并为平均值行打印唯一的行名(例如:item1)。我试过这样的事情:

awk '{for(i=2;i<=NF;i++) sum[i]+=$i} NR%2==0 {print sum[i]/2;sum[i]=0}'

但代码显然不正确,如果有人能指出我做错了什么以及如何改进它以获得预期的结果,我将不胜感激。谢谢!

4

2 回答 2

2

用你的 101 列文件试试这个 awk 解决方案:

 awk 'n<2{for(i=2;i<=NF;i++)a[i]+=$i;n++;}
     n==2{for(i=2;i<=NF;i++)s=s sprintf("%s ",a[i]/2)
         print $1,s;s="";delete a;n=0}' file

如果你喜欢检查NR%2,这也可以:

awk '{for(i=2;i<=NF;i++)a[i]+=$i}
        !(NR%2){for(i=2;i<=NF;i++)s=s sprintf("%s ",a[i]/2) 
        print $1,s;s="";delete a}' file

两条 awk 行的输出与您的示例相同:

item1 15 40 14.5 
item2 -9 106 12.5 

笔记

  • 适用于动态列数
  • 每行末尾都有一个空格,我对此有点懒惰,如果它很重要,也可以将其删除。
于 2013-04-08T19:56:57.203 回答
0

对从第 2 行开始的连续行对求和,以获得动态数量的字段:

$ awk 'NR>1{for(i=2;i<=NF;i++)a[i]+=$i;if(NR%2){printf "%s ",n$1;n="\n";for(i=2;i<=NF;i++)printf "%s ",a[i]/2;delete a}}' file
item1 15 40 14.5 
item2 -9 106 12.5 
于 2013-04-08T19:43:40.143 回答