Questo script illustra un altro modo di fare calcoli con sed
.
In questo caso dobbiamo addizionare numeri che possono essere grandi,
cosa che non è possibile ottenere tramite successivi incrementi
(e probabilmente anche più complesso da ideare, rispetto a questo script).
L’approccio è quello di rappresentare i numeri con lettere, una specie di abaco
implementato con sed
. Le ‘a’ sono unità, le ‘b’ sono
decine e così via: semplicemente si aggiunge il numero di caratteri
sulla riga corrente come unità, e poi si propaga il riporto
alle decine, centinaia, e così via.
Come al solito, i totali provvisori sono mantenuti nell’hold space.
Sull’ultima riga, si converte un’altra volta la notazione dell’abaco
a cifre decimali. Per amor di varietà, questo è fatto tramite un ciclo
piuttosto che con un’ottantina di comandi s
9: prima si
convertono le unità, rimuovendo le ‘a’ dal numero; quindi
le lettere vengono ruotate così che le decine diventano ‘a’, e così
via finché non rimangono più lettere.
#!/usr/bin/sed -nf
# Aggiunge n+1 a all'hold space (+1 è per il newline) s/./a/g H x s/\n/a/
# Esegue il riporto. Le t e le b non sono necessarie, # ma velocizzano le operazioni t a : a; s/aaaaaaaaaa/b/g; t b; b done : b; s/bbbbbbbbbb/c/g; t c; b done : c; s/cccccccccc/d/g; t d; b done : d; s/dddddddddd/e/g; t e; b done : e; s/eeeeeeeeee/f/g; t f; b done : f; s/ffffffffff/g/g; t g; b done : g; s/gggggggggg/h/g; t h; b done : h; s/hhhhhhhhhh//g
: done $! { h b }
# Sull'ultima riga, converte nuovamente in cifre decimali
: loop /a/! s/[b-h]*/&0/ s/aaaaaaaaa/9/ s/aaaaaaaa/8/ s/aaaaaaa/7/ s/aaaaaa/6/ s/aaaaa/5/ s/aaaa/4/ s/aaa/3/ s/aa/2/ s/a/1/
: next y/bcdefgh/abcdefg/ /[a-h]/ b loop p