Como processar um loop while-do e classificar a saída iterada

3

Sou muito novo no Bash Scripting, então perdoe minha ignorância. Eu tenho um arquivo de texto com sobrenomes que estou lendo e processando linha por linha uma média de três resultados de teste. Eu preciso produzir as linhas classificadas pelo sobrenome. Aqui está o que eu tenho que calcular a média, com uma variável chamada OUTTOSORT que eu estava tentando passar para classificar antes de ser saída.

#!/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

Quando executado:

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

Qualquer sugestão sobre como classificar essas linhas depois de computar a média seria muito útil. Obrigado!

Editar:

Muito obrigado pelas suas respostas! Agora tenho um problema em que não é ordenado pelo campo que eu especificar no entanto:

#!/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

Saída:

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)

Como você pode ver, ele está classificando por pontuação média em vez de por Sobrenome, Nome, SID. Eu adicionei um contador para confirmar que estava classificando as linhas da saída. Qual erro está causando a classificação para não usar as chaves corretas? Obrigado!

Editar:

Solução para classificar o problema encontrado: digite flags para o último nome e o primeiro nome deve ser d ao invés de n, tornando o comando sort o comando while loop para sort -k 3,3d -k 4,4d -k 2,2g .

    
por Matt Thompson 08.11.2014 / 02:21

3 respostas

4

Você pode imprimir os resultados para a saída padrão, então canalizar eles para o comando sort:

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
    
por 08.11.2014 / 02:39
2

Os erros no seu código / uso são (pelo menos):

  1. O script chamando: ./Grades.sh Devido a FILE=$1 , ele deve ser ./Grades.sh /path/to/file

  2. OUTTOSORT = : não deve haver um espaço em nenhum dos lados do =

  3. OUTTOSORT = OUTTOSORT + (1): as variáveis devem ser referenciadas com $ , ou seja, OUTTOSORT=$OUTTOSORT

  4. OUTTOSORT = OUTTOSORT + (2): não há concatenação de string em bash .

  5. "...\n" : \n não é uma seqüência de escape em strings normais. Você precisa, por exemplo $'line1\n'

  6. sort < $OUTTOSORT : $OUTTOSORT deve ser um arquivo aqui, mas contém uma string. Você poderia fazer isso com echo "$OUTTOSORT" | sort , mas mais fácil é a combinação do while loop e sort em um pipeline como sugerido pela steeldriver.

por 08.11.2014 / 03:04
1

Depois de corrigir os erros enumerados por Hauke Laging, você pode obter sort para fazer o que quiser, dizendo para fazer uma classificação numérica e usar o terceiro campo (a coluna contendo o sobrenome) como a chave de classificação.

sort -n -k 3

Veja man sort para mais detalhes.

    
por 08.11.2014 / 07:12