0

我正在尝试解析一个 csv 文件(其中包含每个用户的用户 ID 和工作时间)。我编写了以下脚本:

#save weekly average to a file
    while IFS=, read -r col1 col2 col3 col4 col5 col6 col7
    do
        echo "$col2  ($col3+$col4+$col5+$col6+$col7)/5"
    done < user-list.txt

我面临以下两个问题:

  1. 我想跳过 csv 文件的第一行,因为它包含标题
  2. 我正在尝试计算平均值,但 echo 命令不执行表达式。

输入文件中的一些示例数据是:

Computer ID,User ID,M,T,W,T,F
Computer1,User3,5,7,3,5,2

任何帮助,将不胜感激。TIA

4

3 回答 3

0

尝试

awk -F, 'NR > 1 { map[$2]=($3+$4+$5+$6+$7)/5 } END { PROCINFO["sorted_in"]="@val_num_asc";for (i in map) { printf "%s %.2f\n",i,map[i] } }' user-list.txt

通过 -F 使用逗号作为字段分隔符,将第三个、第四个、第五个、第六个和第七个字段相加并除以 5,将结果放入一个名为 map 的数组中,由用户索引 ($2)。忽略 NR > 1 的标题。最后,将数组的排序设置为值数字升序并循环遍历数组,将索引(用户)和值打印到小数点后 2 位。

于 2020-11-19T21:05:17.420 回答
0

对于您的第一个问题,这应该可以解决问题:

#save weekly average to a file
while IFS=, read -r col1 col2 col3 col4 col5 col6 col7
do
    echo "$col2  ($col3+$col4+$col5+$col6+$col7)/5"
done < <tail -n +2 user-list.txt

第二个有点复杂 - echo 命令仅用于显示变量内容或任何类型的输出,不适用于数学表达式。使用如下expr命令:

myvar=$((1 + 2)); result=$(($myvar / 3)); echo $result

像这样的东西,稍微适应你的问题就可以解决它。

于 2020-11-19T21:09:39.740 回答
0

OP 尚未(尚未)提供任何示例输入数据或所需的输出,因此有一些假设:

  • 数据值可以是整数或实数,正数或负数
  • 用户想要每行的平均值(无需计算整个文件的平均值)

一些样本数据:

$ cat user-list.txt
a,b,c,d,e,f,g,h
1,id1,3,4,5,6,7
2,id2,13,14.233,15,16,17
3,id2,3.2,4.3,5.9233,6.0,7.32
4,id4,-3.2,4.3,-15.3,96.0,7.32

一种awk解决方案:

$ awk -F"," 'FNR>=2 { printf "%s %10.3f\n", $2, ($3+$4+$5+$6+$7)/5.0 }' user-list.txt

在哪里:

  • -F","- 使用逗号作为输入字段分隔符
  • FNR>=2- 跳过文件的第一行
  • printf "%s %10.3f\n"%s- 使用格式打印字段 2 ;使用格式打印平均值%10.3f(宽度为 10 w/ 小数点左侧最多 6 位数字加上小数点加上小数点右侧 3 位数字);在末尾添加换行符 ( \n)

以上生成:

id1      5.000
id2     15.047
id2      5.349
id4     17.824

OP 增加了一个新要求……按计算的平均值对输出进行排序,但是,有一些潜在问题需要 OP 进一步输入:

  • 一个用户 ID 可以在数据文件中多次出现吗?
  • 如果一个用户 ID 可以多次出现,那么我们是否需要为每个唯一的用户 ID 生成单行输出,还是为每次出现的用户 ID 生成单独的行?
  • 数据是升序还是降序排序?

现在我要假设:

  • 一个用户 ID 可能在源数据中出现多次(例如,id2在我的示例数据集中 - 上面)。
  • 我们不会为给定的用户 ID 组合多行(即,每行将独立存在)。
  • 我们将按升序和降序显示排序。

虽然可以在内部进行排序,awk但我将选择将awk输出通过管道传输到,sort因为这将需要更少的代码并且(imo)更容易理解。

升序排序:

$ awk -F"," 'FNR>=2 { printf "%s %10.3f\n", $2, ($3+$4+$5+$6+$7)/5.0 }' user-list.txt | sort -nk2
id1      5.000
id2      5.349
id2     15.047
id4     17.824

Wheresort -nk2说使用数字排序按列 #2n排序。

降序排序:

$ awk -F"," 'FNR>=2 { printf "%s %10.3f\n", $2, ($3+$4+$5+$6+$7)/5.0 }' user-list.txt | sort -rnk2
id4     17.824
id2     15.047
id2      5.349
id1      5.000

Wheresort -rnk2说使用numeric 排序按列 #2 排序,但要颠倒r顺序

于 2020-11-19T21:21:26.953 回答