• # un bout de coquillage

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

    Quelles commande(s) allons-nous (re)découvrir aujourd'hui ?
    Voici pour la première partie.

    #!/bin/sh
    # 1ドル: input file
    for c in 'grep' 'sed' 'sort' 'test'
    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 '^[a-zA-Z]+$' "1ドル"
    then
     echo "Found invalid line, check the file!" >&2
     exit 2
    fi
    _if="1ドル"
    _fc=$( mktemp ) # first compartiment
    _sc=$( mktemp ) # second compartiment
    _si='' # shared items
    while IFS= read -r line <&3
    do
     printf '%s' "$line" | cut -c -$(( ${#line}/2 )) |
     sed 's/./&\n/g' | sort -uo "$_fc"
     printf '%s' "$line" | cut -c $(( ${#line}/2 + 1 ))- |
     sed 's/./&\n/g' | sort -uo "$_sc"
     _si="$_si$( comm -12 "$_fc" "$_sc" )"
    done 3<"$_if"
    rm "$_fc" "$_sc"
    #echo "$_si" | cat -vet
    _ps=0 # priority sum
    _ac=0 # ASCII code
    for character in $( echo "$_si" )
    do
     _ac=$( printf '%d' "'$character" )
     case "$character" in
     [a-z]) # a is 97 but should translate to 1
     _ps=$(( _ps + _ac - 96 )) ;;
     [A-Z]) # A is 65 but should translate to 27
     _ps=$(( _ps + _ac - 38 )) ;;
     *) echo "$character=$_ac=??" >&2 ;;
     esac
    done
    echo "$_ps"

    La grande difficulté est que l'écriture suivante (à laquelle j'ai initialement pensée) n'est pas POSIX (c'est une facilité de (ba|k|z)sh mais pas reconnue dans ash par exemple)

    _fc='' # first compartiment
    _sc='' # second compartiment
    _si='' # shared items
    while IFS= read -r line
    do
     _fc="$( printf '%s' "$line" | cut -c -$(( ${#line}/2 )) |
     sed 's/./&\n/g' | sort )"
     _sc="$( printf '%s' "$line" | cut -c $(( ${#line}/2 + 1 ))- |
     sed 's/./&\n/g' | sort )"
     _si="$_si$( comm -12 <( printf '%s' "$_fc" ) <( printf '%s' "$_sc" ) )"
    done <"$_if"

    Pas grave, on troque l'utilisation de RAM (dont la machine où j'ai testé manque un peu) contre des fichiers (j'ai des E/S sur disque assez performantes pour que ce ne soit pas problématique.)

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