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.83 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 la sezione Funzioni di manipolazione di 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 la sezione Funzioni di manipolazione di 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 la sezione Ritagliare campi e colonne).
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]