我试图找出一种比较长制表符分隔文件的第二列中值的方法。在每行的第二列中取一个值:如果下一行(在第二列中)的值比上一行大一个,那么我想对每行的第三列取平均值。例如:
ABC 111 9
ABC 114 4
ABC 115 5
ABC 117 5
并获得:
ABC 111 9
ABC 114 4.5
ABC 117 5
这远远超出了我的低级awk能力。 感谢您的帮助!
答案 0 :(得分:1)
对于您提供的示例,能否请您尝试遵循并让我知道这是否对您有帮助。
awk '
{
if(($NF-prev)==1 && prev){
print val1,val2,(prev+$NF)/2;
val1=val2=prev="";
next}
else if(FNR>1 && prev){
print val1,val2,prev}
}
{
prev=$NF;
val1=$1;
val2=$2
}
END{
if(FNR>1 && prev){
print val1,val2,prev}
}' Input_file
答案 1 :(得分:1)
假设您要合并并平均整个序列(其中后续行比上一行大一遍),以下代码段显示了一种方法:
count == 0 { # For start of first sequence.
count=1; # Set count for first sequence.
last1=$1; first2=$2; last2=$2; sum=$3; # Store starting values.
next # Go on to next line.
}
last2 + 1 == $2 { # Else for lines WITHIN sequence.
count++; # Increment count.
last1=$1; first2=$2; last2=$2; sum+=$3; # Adjust values.
next # On to next line.
}
{ # Else this is a NEW sequence.
print last1" "first2" "sum/count; # Print last sequence.
count=1; # Reset count for new sequence.
last1=$1; first2=$2; last2=$2; sum=$3 # Set starting values.
}
END { # Handle final sequence here.
if (count != 0) { # Only if there were items.
print last1" "first2" "sum/count
}
}
使用该脚本,输入以下数据:
ABC 111 9
ABC 113 4
ABC 114 4
ABC 115 5
ABC 117 5
生成:
ABC 111 9
ABC 113 4.33333
ABC 117 5
它的工作方式是不立即打印有关每一行的详细信息,而是存储该行的详细信息,直到评估下一行。
如果下一行是同一序列的一部分,则其详细信息将汇总为先前的详细信息,然后我们继续进行。
如果下一行是 new 序列的开始,那么我们输出前一个序列(当然,要进行汇总和平均),然后将下一行存储为序列的开始。 / p>
这意味着我们需要一个END
块来处理最终序列,因为没有下一行会强制序列中断。
请注意,由于问题中未提及该字段,因此未将字段1更改考虑在内。为此,只需检测之前,然后检查“ this-field-2比last-field-2大一个”(上面的第二个块),然后继续执行新的顺序即可:
last1!=$1 { # Changed field 1 is new sequence.
print last1" "first2" "sum/count; # Print last sequence.
count=1; # Reset count for new sequence.
last1=$1; first2=$2; last2=$2; sum=$3; # Set starting values.
next # Get next line.
}