我们无法使用awk或制作新文件来存储数据。
我的大脑无法解决这个问题。我们得到一个这样的数据集:
299226663 Laney Camp 70 74 71
434401929 Skyler Camp 78 81 82
199144454 Tracey Camp 77 84 84
我们必须计算平均值,并打印出如下结果:
71 [299226663] Camp, Laney
80 [434401929] Camp, Skyler
81 [199144454] Camp, Tracey
我有单独的bash代码片段都可以工作,但我无法弄清楚如何将它们组合起来。
这样排序正确
sort -t' ' -k3,3 -k2,2 -k1,1n StudentGrades.txt
下一部分肯定是错误的,我希望它会被撕裂,但它会计算平均值并打印正确的格式,除非它因为某些原因跳过了StudentGrades.txt的最后一行:
filename='StudentGrades.txt'
while read LINE
do
var1=$(echo $LINE | cut -d' ' -f1)
var2=$(echo $LINE | cut -d' ' -f2)
var3=$(echo $LINE | cut -d' ' -f3)
var4=$(echo $LINE | cut -d' ' -f4)
var5=$(echo $LINE | cut -d' ' -f5)
var6=$(echo $LINE | cut -d' ' -f6)
let a=(var4+var5+var6)/3
echo $a [$var1] $var3, $var2
done < StudentGrades.txt
我无法找到获得平均值,格式化和排序的方法,而无需将第二个脚本移动到新文件并在其上调用sort命令。有任何想法吗?它可能会采取更大的变化,因为我对第二部分没有信心。
答案 0 :(得分:1)
我不知道为什么你对平均循环如此持怀疑态度:除了你是整数之外,看起来还不错。
没有任何改变,或多或少简单地将它们全部输送到一起:
#!/bin/bash
input_file="StudentGrades.txt"
(cat "$input_file" ; echo "") | \
sort -t' ' -k3,3 -k2,2 -k1,1n | \
while read LINE
do
var1=$(echo $LINE | cut -d' ' -f1)
var2=$(echo $LINE | cut -d' ' -f2)
var3=$(echo $LINE | cut -d' ' -f3)
var4=$(echo $LINE | cut -d' ' -f4)
var5=$(echo $LINE | cut -d' ' -f5)
var6=$(echo $LINE | cut -d' ' -f6)
let a=(var4+var5+var6)/3
echo $a [$var1] $var3, $var2
done
仅在文件的最后一行未正确读取的情况下才需要echo ""
之后的cat
(这是因为read
等待换行符,但您的文件可能是并不以换行结束。)
\
符号使得它看起来好像代码中没有换行符,因此命令通过管道连接在一起。通过添加足够的分号,如果你真的想要,你甚至可以把它写成一行。
由@JonathanLeffler提出的重构:
#!/bin/bash
input_file="StudentGrades.txt"
(cat "$input_file" ; echo "") | \
sort -t' ' -k3,3 -k2,2 -k1,1n | \
while read num_id name surname points1 points2 points3
do
let average=(points1+points2+points3)/3
echo ${average} [${num_id}] $surname, $name
done
似乎与其他版本一样工作。
哈,在bash中学到了新东西!谢谢@JonathanLeffler! :)答案 1 :(得分:0)
关于丢失的最后一行问题,这是read
命令的常见缺陷
因为如果该行末尾不包含换行代码,则返回false
该行的常常出现在最后一行,具体取决于文本编辑器
要解决此问题,请尝试while read LINE || [ -n "${LINE}" ]
而不是while read LINE
除此之外,请考虑说set -- $LINE
而不是分别使用cut
命令。它会自动将每列分配到正面参数$ 1,$ 2等等。然后你的脚本将更快地工作。
BTW你的平均计算截断小数部分而不将其四舍五入到最接近的整数。那可以吗?
总结一下,我会修改你的脚本如下:
#!/bin/bash
sort -t' ' -k3,3 -k2,2 -k1,1n StudentGrades.txt | while read LINE || [ -n "${LINE}" ]; do
set -- $LINE
let a=($4*10 + $5*10 +$6*10 + 15)/30
# If you want to preserve the 1st decimal place, replace the line above with:
# a=$( echo $(( ($4*10 + $5*10 +$6*10 ) / 3 )) | sed -e "s/\(.\)$/.\1/" )
echo $a [$1] $3, $2
done