Как сохранить в списке / массиве первые части строки, а затем отсортировать их в зависимости от второй части? - PullRequest
1 голос
/ 23 октября 2019

У меня есть школьный проект, который дает мне несколько строк в тексте, подобном следующему:

  • team1-team2: 2-1
  • team3-team1: 2-2
  • и т. Д.

он хочет, чтобы я определил, какая команда выиграла (или сыграл вничью), а затем составил с ними таблицу лиги, начисляя очки за победы / ничьи.

я впервые использую bash. я сохранил имена team1 / team2 в переменной, а затем сделал то же самое для целей. как мне составить стол? мне удалось заставить мой сценарий создать новый файл, который сохраняет там все названия команд (и проверяет наличие дубликатов), но я не знаю, как продолжить. Должен ли я сделать массив для каждой команды, сохраняя там свои результаты? а затем, как мне реализовать рейтинги, например

  • team1 3p
  • team2 1p
  • и т. д.

я не спрашиваюдля реального кода, просто руководство о том, как я должен его реализовать. делает новый файл правильным ходом? я должен попробовать создать новый массив с командами вместо этого? или что-то еще?

Ответы [ 2 ]

2 голосов
/ 23 октября 2019

Проблема может быть разделена на 3 части:

  1. Считывание входных данных в память в формате, которым легко манипулировать.
  2. Манипулирование данными в памяти
  3. Вывод результатов в нужном формате.

При чтении данных в память, вы можете решить прочитать все данные за один раз, прежде чем манипулировать ими. Или вы можете решить читать входные данные по одной строке за раз и манипулировать каждой строкой во время чтения. При использовании языков сценариев оболочки, таких как bash, второй вариант обычно приводит к более простому коду.

Самое важное решение, которое необходимо принять, - это то, как вы хотите структурировать данные в памяти. Обычно вы хотите избежать дублирования данных и, как правило, хотите, чтобы структура данных была легко преобразована в желаемый результат. В этом случае наиболее логичной структурой данных является ассоциативный массив, использующий имя команды в качестве ключа.

Предполагая, что вам нужно использовать bash, вот структура, на которую вы можете опираться:

#!/bin/bash

declare -A results
while IFS=':-' read team1 team2 score1 score2; do
  if [ ${score1} -gt ${score2} ]; then
    ((results[${team1}]+=2))
  elif [ ...next test... ]; then
    ...
  else
    ...
  fi
done < scores.txt

# Now you have an associative array containing the points for each team.
# You can either output it as it stands, or sort it by piping through the
# 'sort' command.

for key in $[!results[@]}; do
  echo ...
done
1 голос
/ 23 октября 2019

Я бы использовал awk для этого

AWK - это интерпретируемый язык программирования (AWK расшифровывается как Aho, Weinberger, Kernighan), предназначенный для обработки текста и обычно используемый в качестве данных. инструмент извлечения и отчетности. AWK в основном используется в Unix-системах.

Использование сценариев с использованием чистого bash часто бывает бесполезным для такого рода задач.

Позвольте мне показать вам, насколько легко это можно сделать с помощью awk

Входной файл: scores.txt

team1-team2:2-1
team3-team1:2-2

Код:

awk -F'[:-]' ' # set delimiters to ':' or '-'
    {
        if($3>$4){teams[$1] += 3} # first team gets 3 points
        else if ($3<$4){teams[$2] += 3} # second team gets 3 points
        else {teams[$1]+=1; teams[$2]+=1} # both teams get 1 point
    }
    END{ # after scanning input file
        for(team in teams){
            print(team OFS teams[team]) # print total points per team
        }
    }' scores.txt | sort -rnk 2 > ranking.txt # sort by nb of points

Выходные данные (rating.txt):

team1 4
team3 1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...