Bash Shell: обновить порядок учеников в файле, обновив их оценки - PullRequest
0 голосов
/ 09 апреля 2020

Итак, у меня есть 2 файла, которые имеют очень похожий формат:

файл average_grades

ID First_Name Last_Name(s) Average_Grade
323 Dospinescu Arianna 10.00
326 Balan Ionut 9.87
327 Balan Teodor-Raul 9.80
329 Popescu Iulian-Gabriel 9.56
317 Tabarcea Andreea 9.48
365 Negruzzi Marian 9.23
398 Acatrinei Andrei 9.00
365 Popescu Anca-Maria 8.76

и файл summer_marks

ID First_Name Last_Name(s) Summer_Grades
326 Balan Ionut 10 10 10 10 10
327 Balan Teodor-Raul 9 8 7 6 5
329 Popescu Iulian-Gabriel 4 5 6 7 8
365 Negruzzi Marian 4 5 6 7 8
398 Acatrinei Andrei 7 7 7 7 7
387 Popescu Anca-Maria 1 2 3 4 5
317 Tabarcea Andreea 9 8 7 6 5
323 Dospinescu Arianna 9 10 9 10 9

Я хочу написать оболочку, которая получает 2 файла в качестве параметров и обновляет оценки в average_grades следующим образом: вычислите среднее из 5 оценок, которые каждый студент получил летом, затем среднее между этим результатом и уже существующей средней оценкой (в последнем столбце в average_grades ); обновите last_colum и выполните повторную сортировку average_grades по новым значениям в последнем столбце. Как я могу это сделать? Примечание. Гарантируется, что идентификатор каждого учащегося является уникальным

. Я пытался использовать awk, но не смог. Я хотел перебрать каждую строку в summer_marks , вычислить среднее значение для каждых 5 марок и сохранить эти значения в массиве, а затем снова перебрать каждую строку в average_grades , вычислить новое среднее и обновите последний столбец, затем выполните повторную сортировку.

1 Ответ

3 голосов
/ 09 апреля 2020

Ваше описание очень близко. Вы пройдете через summer_marks (используя NR==FNR в качестве условия правила) и усредните последние 5 оценок. Затем вы увеличите l oop свыше average_grades и добавите среднее к текущему среднему и разделите его на 2 (или взвесите, как вам нравится). Вы можете использовать NR>FNR для второго условия правила. Вы можете использовать ID в качестве индекса для вашего массива, а затем сопоставить его с индексом в average_grades, чтобы сохранить правильность индексации. Пока average_grades находится в нужном порядке сортировки, повторная сортировка не требуется, например,

awk 'NR==FNR && FNR>1 {
        n=0
        sum=0
        for(i=4;i<=NF;i++) {
            sum+=$i
            n++;
        }
        avg=sum/n
        id[$1]=avg
    }
    NR>FNR {
        if($1 in id) {
            $NF+=id[$1]
            $NF/=2
        }
        print $0
    }
' summer_marks average_grades

Пример вывода

ID First_Name Last_Name(s) Average_Grade
323 Dospinescu Arianna 9.7
326 Balan Ionut 9.935
327 Balan Teodor-Raul 8.4
329 Popescu Iulian-Gabriel 7.78
317 Tabarcea Andreea 8.24
365 Negruzzi Marian 7.615
398 Acatrinei Andrei 8
365 Popescu Anca-Maria 7.38

Если вы хотите отсортировать по убыванию по новым средним, вы можете направить результаты в | sort -k4r, и это даст

Сортированный вывод

ID First_Name Last_Name(s) Average_Grade
326 Balan Ionut 9.935
323 Dospinescu Arianna 9.7
327 Balan Teodor-Raul 8.4
317 Tabarcea Andreea 8.24
398 Acatrinei Andrei 8
329 Popescu Iulian-Gabriel 7.78
365 Negruzzi Marian 7.615
365 Popescu Anca-Maria 7.38
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...