Successivo: Programma labels, Precedente: Programma alarm, Su: Programmi vari [Contenuti][Indice]
Il programma di utilità di sistema tr
rimpiazza caratteri. Per
esempio, è spesso usato per trasformare lettere maiuscole in lettere minuscole
in vista di ulteriori elaborazioni:
generare dei dati | tr 'A-Z' 'a-z' | elaborare dei dati …
tr
richiede due liste di caratteri.82 Quando
si elabora l’input, il primo carattere della prima lista è rimpiazzato con il
primo carattere della seconda lista, il secondo carattere della prima lista è
rimpiazzato con il secondo carattere della seconda lista, e così via. Se ci
sono più caratteri nella lista “da” che in quella “a”, l’ultimo carattere
della lista “a” è usato per i restanti caratteri della lista “da”.
In un lontano passato,
un utente propose di aggiungere una funzione di traslitterazione a
gawk
.
Il programma seguente è stato scritto per dimostrare che la traslitterazione
di caratteri poteva essere fatta con una funzione definita dall’utente.
Questo programma non è così completo come il programma di utilità di sistema
tr
, ma svolge buona parte dello stesso lavoro.
Il programma translate
è stato scritto molto prima che gawk
fosse in grado di separare ciascun carattere di una stringa in elementi
distinti di un vettore. Questo è il motivo per cui usa ripetutamente le
funzioni predefinite substr()
, index()
, e gsub()
(vedi Funzioni per stringhe).
Ci sono due funzioni. La prima, traduci_stringa()
,
richiede tre argomenti:
da
Una lista di caratteri da cui traslitterare
a
Una lista di caratteri a cui traslitterare
stringa
La stringa su cui effettuare la traslitterazione
I vettori associativi facilitano molto la parte di traslitterazione.
vettore_trad
contiene i caratteri “a”, indicizzato dai
caratteri “da”. Poi un semplice
ciclo scandisce da
, un carattere alla volta. Per ogni carattere
in da
, se il carattere compare in stringa
è rimpiazzato con il corrispondente carattere a
.
La funzione traducilo()
chiama traduci_stringa()
, usando $0
come stringa. Il programma principale imposta due variabili globali, DA
e
A
, dalla riga di comando, e poi modifica ARGV
in modo che
awk
legga dallo standard input.
Infine, la regola di elaborazione si limita a chiamare traducilo()
per ogni record:
# translate.awk --- fa cose simili al comando tr # Bug: non gestisce cose del tipo tr A-Z a-z; deve essere # descritto carattere per carattere. # Tuttavia, se `a' è più corto di `da', # l'ultimo carattere in `a' è usato per il resto di `da'. function traduci_stringa(da, a, stringa, lf, lt, lstringa, vettore_trad, i, c, risultato) { lf = length(da) lt = length(a) lstringa = length(stringa) for (i = 1; i <= lt; i++) vettore_trad[substr(da, i, 1)] = substr(a, i, 1) if (lt < lf) for (; i <= lf; i++) vettore_trad[substr(da, i, 1)] = substr(a, lt, 1) for (i = 1; i <= lstringa; i++) { c = substr(stringa, i, 1) if (c in vettore_trad) c = vettore_trad[c] risultato = risultato c } return risultato } function traducilo(da, a) { return $0 = traduci_stringa(da, a, $0) } # programma principale BEGIN {
if (ARGC < 3) { print "sintassi: translate da a" > "/dev/stderr" exit }
DA = ARGV[1] A = ARGV[2] ARGC = 2 ARGV[1] = "-" } { traducilo(DA, A) print }
È possibile effettuare la traslitterazione di caratteri in una funzione a
livello utente, ma non è detto che sia efficiente, e noi (sviluppatori
di gawk
) abbiamo iniziato a prendere in considerazione l’aggiunta di una funzione.
Tuttavia, poco dopo aver scritto questo programma, abbiamo saputo che Brian
Kernighan aveva aggiunto le funzioni toupper()
e tolower()
alla
sua versione di awk
(vedi Funzioni per stringhe). Queste
funzioni gestiscono la maggior parte dei casi in cui serva la traslitterazione
di caratteri, e quindi abbiamo deciso di limitarci ad aggiungere le stesse
funzioni a gawk
, e di disinteressarci del resto.
Un miglioramento ovvio a questo programma sarebbe di impostare il vettore
vettore_trad
solo una volta, in una regola BEGIN
. Tuttavia, ciò
presuppone che le liste “da” e “a” non cambino mai durante tutta
l’esecuzione del programma.
Un altro miglioramento ovvio è di consentire l’uso di intervalli, come
‘a-z’, come consentito dal programma di utilità tr
. Si può
trarre ispirazione dal codice di cut.awk (vedi Programma cut).
Su alcuni sistemi
più datati, incluso Solaris, la versione di sistema di tr
può
richiedere che le liste siano scritte come espressioni di intervallo,
racchiuse in parentesi quadre
(‘[a-z]’) e tra apici, per evitare che la shell effettui
espansioni di nome-file. Questo non è un miglioramento.
Successivo: Programma labels, Precedente: Programma alarm, Su: Programmi vari [Contenuti][Indice]