Successivo: Separazione in base al contenuto, Precedente: Separatori di campo, Su: Leggere file [Contenuti][Indice]
Questa
sezione tratta una funzionalità avanzata
di gawk
. Se si è un utente alle prime armi di awk
,
la si può saltare in prima lettura.
gawk
fornisce una funzionalità per il trattamento di campi
a larghezza fissa senza un separatore di campo distintivo. Per esempio,
dati di questo tipo si trovano nell’input per vecchi programmi Fortran dove
dei numeri sono elencati uno dopo l’altro, o nell’output di programmi che
non prevedono che il loro output sia dato in input ad altri programmi.
Un esempio di quest’ultimo caso è una tabella dove tutte le colonne sono
allineate usando un numero variabile di spazi e dove i campi vuoti
sono solo spazi. Chiaramente, la normale divisione in campi di
awk
basata su FS
non funziona bene in questa situazione.
Sebbene un programma awk
portabile possa usare una serie di chiamate substr()
su $0
(vedi Funzioni per stringhe),
questo è scomodo e inefficiente se il numero dei campi è elevato.
La suddivisione di un record in input in campi a larghezza fissa viene
specificata assegnando una stringa contenente numeri separati da spazi alla
variabile predefinita FIELDWIDTHS
. Ogni numero specifica la larghezza
del campo, comprese le colonne tra i campi. Se si vogliono ignorare le
colonne tra i campi si può specificare la loro larghezza come un campo
separato che verrà poi ignorato.
È un errore fatale definire una larghezza di campo che abbia un valore
negativo. I dati seguenti costituiscono l’output del programma di utilità
Unix w
. È utile per spiegare l’uso di FIELDWIDTHS
:
10:06pm up 21 days, 14:04, 23 users User tty login idle JCPU PCPU what hzuo ttyV0 8:58pm 9 5 vi p24.tex hzang ttyV3 6:37pm 50 -csh eklye ttyV5 9:53pm 7 1 em thes.tex dportein ttyV6 8:17pm 1:47 -csh gierd ttyD3 10:00pm 1 elm dave ttyD4 9:47pm 4 4 w brent ttyp0 26Jun91 4:46 26:46 4:41 bash dave ttyq4 26Jun9115days 46 46 wnewmail
Il seguente programma prende l’input sopra mostrato, converte il tempo di inattività in numero di secondi, e stampa i primi due campi e il tempo di inattività calcolato:
BEGIN { FIELDWIDTHS = "9 6 10 6 7 7 35" } NR > 2 { inat = $4 sub(/^ +/, "", inat) # togli spazi prima del valore if (inat == "") inat = 0 if (inat ~ /:/) { split(inat, t, ":") inat = t[1] * 60 + t[2] } if (inat ~ /days/) inat *= 24 * 60 * 60 print $1, $2, inat }
NOTA: Questo programma usa diverse funzionalità di
awk
non ancora trattate.
L’esecuzione del programma sui dati produce il seguente risultato:
hzuo ttyV0 0 hzang ttyV3 50 eklye ttyV5 0 dportein ttyV6 107 gierd ttyD3 1 dave ttyD4 0 brent ttyp0 286 dave ttyq4 1296000
Un altro esempio (forse più pratico) di dati di input con larghezza costante è l’input da un mazzo di schede elettorali. In alcune parti degli Stati Uniti, i votanti marcano le loro scelte perforando delle schede elettroniche.
Queste schede vengono poi elaborate per contare i voti espressi per ogni
singolo candidato o su ogni determinato quesito. Siccome un votante può
scegliere di non votare su alcune questioni, qualsiasi colonna della scheda
può essere vuota. Un programma awk
per elaborare tali dati potrebbe
usare la funzionalità FIELDWIDTHS
per semplificare la lettura dei dati.
(Naturalmente, riuscire a eseguire gawk
su un sistema con lettori di
schede è un’altra storia!)
L’assegnazione di un valore a FS
fa sì che gawk
usi FS
per separare nuovamente i campi. Si può usare ‘FS = FS’ per ottenere
questo effetto, senza dover conoscere il valore corrente di FS
.
Per vedere quale tipo di separazione sia in atto,
si può usare PROCINFO["FS"]
(vedi Variabili auto-assegnate).
Il suo valore è "FS"
se si usa la normale separazione in campi,
o "FIELDWIDTHS"
se si usa la separazione in campi a larghezza fissa:
if (PROCINFO["FS"] == "FS") separazione in campi normale… else if (PROCINFO["FS"] == "FIELDWIDTHS") separazione in campi a larghezza fissa… else separazione dei campi in base al contenuto… (si veda la sezione successiva)
Quest’informazione è utile quando si scrive una funzione che
necessita di cambiare temporaneamente FS
o FIELDWIDTHS
,
leggere alcuni record, e poi ripristinare le impostazioni originali
(vedi Funzioni Passwd,
per un esempio di tale funzione).
Successivo: Separazione in base al contenuto, Precedente: Separatori di campo, Su: Leggere file [Contenuti][Indice]