如何使用awk计算异常
How to calculate anomaly using awk
A 有一个文件:
file.txt
1 32
2 34
3 32
4 43
5 25
6 34
7 65
8 34
9 23
10 44
我想在发送列中查找异常:
考虑到第 2 行到第 10 行的值,我的以下脚本打印异常。它没有考虑第 1 行值。
awk 'FNR==NR{
f=1;
if( >= 1 && <= 10){
count++;
SUM+=;
};
next
}
FNR==1 && f==1{
AVG=SUM/count;
next
}
( >= 1 && <= 10){
print , -AVG
}
' file.txt file.txt
我的愿望输出:
1 -4.6
2 -2.6
3 -4.6
4 6.4
5 -11.6
6 -2.6
7 28.4
8 -2.6
9 -13.6
10 7.4
我找到了解决方法:
awk '{f=>=1 && <=10}f && NR==FNR{sum+=; c++; next}f{ print , -(sum/c) }' file.txt file.txt
我仍然想知道为什么第一个脚本没有给出正确答案。
OP 中的第一个脚本没有给出正确的值,因为您在文件的第二遍中跳过了第一行。这可以在语句 (FNR==1 && f==1) { AVG=sum/count; next }
中看到。由于 next
语句,您跳过计算与第一条记录的平均值的偏差。
这是在两次传递中对平均值偏差的有效计算:
awk '(NR==FNR){s+=;c++;next}
(FNR==1){s/=c}
{print ,-s}' file file
如果 file
在第一列中包含大于 10 或小于 1 的值,但您只想查看 [0,10]
范围内的值,那么您可以执行以下操作:
awk '(<1 || >10) {next}
(NR==FNR){s+=;c++;next}
(FNR==1){s/=c}
{print ,-s}' file file
还有其他优化可以完成,但这些只有在处理非常大的文件(数百万行)时才有用。
由于这只是 2 列文件,因此可以一次性完成 awk
还有:
awk '{map[] = ; s += }
END {mean = s/NR; for (i in map) print i, map[i] - mean}' file
1 -4.6
2 -2.6
3 -4.6
4 6.4
5 -11.6
6 -2.6
7 28.4
8 -2.6
9 -13.6
10 7.4
A 有一个文件:
file.txt
1 32
2 34
3 32
4 43
5 25
6 34
7 65
8 34
9 23
10 44
我想在发送列中查找异常:
考虑到第 2 行到第 10 行的值,我的以下脚本打印异常。它没有考虑第 1 行值。
awk 'FNR==NR{
f=1;
if( >= 1 && <= 10){
count++;
SUM+=;
};
next
}
FNR==1 && f==1{
AVG=SUM/count;
next
}
( >= 1 && <= 10){
print , -AVG
}
' file.txt file.txt
我的愿望输出:
1 -4.6
2 -2.6
3 -4.6
4 6.4
5 -11.6
6 -2.6
7 28.4
8 -2.6
9 -13.6
10 7.4
我找到了解决方法:
awk '{f=>=1 && <=10}f && NR==FNR{sum+=; c++; next}f{ print , -(sum/c) }' file.txt file.txt
我仍然想知道为什么第一个脚本没有给出正确答案。
OP 中的第一个脚本没有给出正确的值,因为您在文件的第二遍中跳过了第一行。这可以在语句 (FNR==1 && f==1) { AVG=sum/count; next }
中看到。由于 next
语句,您跳过计算与第一条记录的平均值的偏差。
这是在两次传递中对平均值偏差的有效计算:
awk '(NR==FNR){s+=;c++;next}
(FNR==1){s/=c}
{print ,-s}' file file
如果 file
在第一列中包含大于 10 或小于 1 的值,但您只想查看 [0,10]
范围内的值,那么您可以执行以下操作:
awk '(<1 || >10) {next}
(NR==FNR){s+=;c++;next}
(FNR==1){s/=c}
{print ,-s}' file file
还有其他优化可以完成,但这些只有在处理非常大的文件(数百万行)时才有用。
由于这只是 2 列文件,因此可以一次性完成 awk
还有:
awk '{map[] = ; s += }
END {mean = s/NR; for (i in map) print i, map[i] - mean}' file
1 -4.6
2 -2.6
3 -4.6
4 6.4
5 -11.6
6 -2.6
7 28.4
8 -2.6
9 -13.6
10 7.4