Bash:读取CSV文本文件后,从多个列中查找条目的平均值



我正在尝试读取CSV文本文件,并查找所有用户ID(第2列(以偶数(2,4,6,…(结尾的每周平均小时数(第3列至第7列(。

输入样本如下:

Computer ID,User ID,M,T,W,T,F
Computer1,User3,5,7,3,5,2
Computer2,User5,8,8,8,8,8
Computer3,User4,0,8,0,8,4
Computer4,User1,5,4,5,5,8
Computer5,User2,9,8,10,0,0
Computer6,User7,4,7,8,2,5
Computer7,User6,8,8,8,0,0
Computer8,User9,5,2,0,6,8
Computer9,User8,2,5,7,3,6
Computer10,User10,8,9,9,9,10

我写了以下脚本:

awk -F, '$2~/[24680]$/{for(i=3;i<=7;i++){a+=$i};printf "%st%.2gn",$2,a/5;a=0}' user-list.txt > superuser.txt

这个脚本的输出是:

User4   4
User2   5.4
User6   4.8
User8   4.6
User10  9

但是,我想将脚本更改为只打印以偶数结尾的所有用户ID的一个平均值。

所需的输出如下(从技术上讲,这是以偶数结尾的ID的所有小时的平均值(:

5.56

如有任何帮助,我们将不胜感激。

TIA-

尝试在这里修复OP的尝试,并添加逻辑以获得文件最后读取时的平均值。写在手机上,所以无法测试它应该可以工作,以防我根据OP的描述得到正确的想法。

awk -F, '
$2~/[24680]$/{
count++
for(i=3;i<=7;i++){
sum+=$i
}
tot+=sum/5
sum=0
}
END{
print "Average of averages is: " (count?tot/count:"NaN")
}
' user-list.txt > superuser.txt

您可以尝试:

awk -F, '$2 ~ /[02468]$/ {
for(i=3; i<=7; i++) {
s += $i
++n
}
}
END {
if (n)
printf "%.2fn", s/n
}' cust.csv
5.56
awk -F, 'NR == 1 { next } { match($2,/[[:digit:]]+/);num=substr($2,RSTART,RLENGTH);if(num%2==0) { av+=($3+$4+$5+$6+$7)/5 } } END { printf "%.2fn",av/5}' user-list.txt

忽略第一个标题,如。使用awk的匹配函数从userid中选择数字。将num变量设置为此数字。检查数字是否与num%2偶数。如果是平均值,则将变量av设置为av加上平均值。最后,将平均值打印到小数点后2位。

打印所有偶数用户ID的日均值:

#!/bin/sh
awk -F , '
(NR>1) &&
($2 ~ /[02468]$/) {
hours += ($3 + $4 + $5 + $6 + $7)
(users++)
}
END {
print (hours/users/5)
}' 
"$1"

用法示例:

$ script user-list
5.56

得到整数的均匀性或奇异性的一种方法是使用模(%(,如N % 2。对于N的偶数值,此和的值为零,对于奇数值,其值为1。

然而,在这种情况下,以任何方式提取数字都需要字符串操作,因此也可以只使用单个字符串匹配来获得奇数或偶数。

此外,IMO,对于5个字段(一周中的几天(不会改变,直接添加它们而不是循环更简洁。(NR>1)也跳过标题行,以防发生冲突。

最后,对于奇数用户,您当然可以将/[02468]$/替换为/[13579]$/以获得相同的数据。