• # un bout de shell...

    Posté par (site web personnel, Mastodon) . En réponse au message Avent du Code, jour 1. Évalué à 1.

    ...POSIX pour l'argent

    #!/bin/sh
    ##########################################################################
    # 1ドル: input file
    # 2ドル: output file
    for c in 'grep' 'tail' 'test' 'sort'
    do
     if ! command -v "$c" >/dev/null
     then
     echo "Error: command '$c' not found" >&2
     exit 3
     fi
    done
    if test -z "1ドル"
    then
     echo "Please call me with an input file..." >&2
     exit 1
    fi
    if grep -Eqsv '^$|^[0-9]+$' "1ドル"
    then
     echo "Found line neither empty nor with integer" >&2
     exit 2
    fi
    _if="1ドル"
    test -z $( tail -n 1 "$_if" ) && echo >>"$_if"
    _of="${2:-out01.txt}"
    printf '' >"$_of"
    _tn="${3:-1}"
    _ec=0 # total calories count
    _er=0 # rank in input file
    while IFS= read -r line <&3
    do
     if test -z "$line"
     then
     _er=$(( _er + 1 ))
     if test $_ec -ne 0
     then
     echo "$_er:$_ec" >>"$_of"
     _ec=0
     fi
     else
     _ec=$(( _ec + line ))
     fi
    done 3< "$_if"
    sort -k 2 -t ':' -n "$_of" | tail -n 1

    Le fichier de sortie permet de simplifie d'une part (c'est faisable de tout faire en mémoire mais c'est plus de code pas forcément lisible) et sert de contrôle d'autre part. (c'est ce qui a permis de détecter une petite erreur subtile corrigée par le echo >>"$_if") Ainsi, avec l'exemple donné dans l'énoncé, il contient :

    1:6000
    2:4000
    3:11000
    4:24000
    5:10000

    Le stockage du rang n'est pas forcément utile dans l'immédiat mais ça me permet de savoir le numéro de la ligne renvoyée en résultat.

    "It is seldom that liberty of any kind is lost all at once." ― David Hume