如何处理 while-do 循环并对迭代输出进行排序

如何处理 while-do 循环并对迭代输出进行排序

我对 Bash 脚本很陌生,所以请原谅我的无知。我有一个包含姓氏的文本文件,我正在逐行读取和处理三个测试分数的平均值。我需要输出按姓氏排序的行。这是我必须计算平均值的内容,其中包含一个名为 OUTTOSORT 的变量,我试图在输出之前将其传递给排序。

#!/bin/bash
FILE=$1
OUTTOSORT=""

while read -r SID FIRST LAST S1 S2 S3
do
    SUM=$(expr $S1 + $S2 + $S3)
    AVG=$(expr $SUM / 3)
    OUTTOSORT = OUTTOSORT + "$AVG [$SID] $LAST, $FIRST \n"
done < "$FILE"

sort < $OUTTOSORT

运行时:

engr2-6-52-dhcp:homework6 Matt$ ./Grades.sh 
./Grades.sh: line 10: : No such file or directory
./Grades.sh: line 12: $OUTTOSORT: ambiguous redirect

关于如何在计算平均值后对这些行进行排序的任何建议都会非常有帮助。谢谢!

编辑:

非常感谢您的回答!我现在遇到一个问题,它没有按我指定的字段排序:

#!/bin/bash
FILE=$1
COUNT=0
while read -r SID FIRST LAST S1 S2 S3 
do
    SUM=$(expr $S1 + $S2 + $S3)
    AVG=$(expr $SUM / 3)
    printf '%d [%d] %s, %s (%d)\n' "$AVG" "$SID" "$LAST" "$FIRST" "$COUNT"
    COUNT=$((COUNT + 1))
done < "$FILE" | sort -k 3,3n -k 4,4n -k 2,2g

输出:

71 [299226663] Camp, Laney (5)
80 [434401929] Camp, Skyler (6)
81 [199144454] Camp, Tracey (4)
82 [123456789] Johnson, Lee (0)
82 [928441032] Forester, Jess (7)
91 [999999999] Smith, Jaime (1)
92 [888111818] Forney, JC (2)
93 [928441032] Forester, Chris (8)
99 [290010111] Lee, Terry (3)

正如您所看到的,它是按平均分排序,而不是按姓氏、名字、SID 排序。我添加了一个计数器来确认它正在对输出的各行进行排序。什么错误导致排序不使用正确的键?谢谢!

编辑:

找到排序问题的解决方案:姓氏和名字的类型标志应该是 d 而不是 n,使 while 循环命令的排序命令通过管道传送到sort -k 3,3d -k 4,4d -k 2,2g

答案1

您可以将结果打印到标准输出,然后管道将它们传递给排序命令:

while read -r SID FIRST LAST S1 S2 S3
do
     SUM=$(expr $S1 + $S2 + $S3)
     AVG=$(expr $SUM / 3)
     printf '%d [%d] %s, %s\n' "$AVG" "$SID" "$LAST" "$FIRST"
done < "$FILE" | sort

答案2

您的代码/使用中的错误(至少)是:

  1. 脚本调用:./Grades.sh由于FILE=$1它必须是./Grades.sh /path/to/file

  2. OUTTOSORT =: 两边不能有空格=

  3. OUTTOSORT = OUTTOSORT +(1) :变量必须用a引用$,即OUTTOSORT=$OUTTOSORT

  4. OUTTOSORT = OUTTOSORT +(2) : 中不存在这样的字符串连接bash

  5. "...\n":\n不是普通字符串中的转义序列。例如,您需要$'line1\n'

  6. sort < $OUTTOSORT:$OUTTOSORT这里必须是一个文件,但它包含一个字符串。您可以这样做,但更容易的是循环​​和管道echo "$OUTTOSORT" | sort的组合,如 Steeldriver 建议的那样。whilesort

答案3

一旦修复了 Hauke Laging 枚举的错误,您就可以sort通过告诉它进行数字排序并使用第三个字段(包含姓氏的列)作为排序键来完成您想要的操作。

sort -n -k 3

请参阅man sort了解更多详情。

相关内容