Successivo: Controllare la creazione di campi, Precedente: Dimensione costante, Su: Leggere file [Contenuti][Indice]
• File CSV | Ancora sui file CSV. |
Questa
sezione tratta una funzionalità avanzata
di gawk
. Se si è un utente alle prime armi di awk
,
la si può saltare in prima lettura.
Normalmente, quando si usa FS
, gawk
definisce i campi come
le parti del record che si trovano tra due separatori di campo. In altre
parole, FS
definisce cosa un campo non è, invece di cosa
è.
Tuttavia, ci sono casi in cui effettivamente si ha bisogno di definire i campi
in base a cosa essi sono, e non in base a cosa non sono.
Il caso più emblematico è quello dei dati cosiddetti comma-separated value (CSV). Molti fogli elettronici, per esempio, possono esportare i dati in file di testo, dove ogni record termina con un ritorno a capo e i campi sono separati tra loro da virgole. Se le virgole facessero solo da separatore fra i dati non ci sarebbero problemi. Il problema sorge se uno dei campi contiene una virgola al suo interno. In queste situazioni, la maggioranza dei programmi include il campo fra doppi apici.24 Così, potremmo avere dei dati di questo tipo:
Robbins,Arnold,"1234 A Pretty Street, NE",MyTown,MyState,12345-6789,USA
La variabile FPAT
offre una soluzione per casi come questo.
Il valore di FPAT
dovrebbe essere una stringa formata da un’espressione
regolare. L’espressione regolare descrive il contenuto di ciascun campo.
Nel caso dei dati CSV visti prima, ogni campo è “qualsiasi cosa che non
sia una virgola,” oppure “doppi apici, seguiti da qualsiasi cosa che non
siano doppi apici, e doppi apici di chiusura”. (Ci sono definizioni di
dati CSV più complicate, vedere più sotto.)
Se fosse scritta come una
costante regexp
(vedi la sezione Espressioni regolari),
sarebbe /([^,]+)|("[^"]+")/
.
Dovendola scrivere come stringa si devono proteggere i doppi apici,
e quindi si deve scrivere:
FPAT = "([^,]+)|(\"[^\"]+\")"
Come esempio pratico, si può vedere questo semplice programma che analizza e divide i dati:
BEGIN { FPAT = "([^,]+)|(\"[^\"]+\")" }
{ print "NF = ", NF for (i = 1; i <= NF; i++) { printf("$%d = <%s>\n", i, $i) } }
Eseguendolo, avendo in input la riga vista sopra, si ottiene:
$ gawk -f simple-csv.awk addresses.csv NF = 7 $1 = <Robbins> $2 = <Arnold> $3 = <"1234 A Pretty Street, NE"> $4 = <MyTown> $5 = <MyState> $6 = <12345-6789> $7 = <USA>
Si noti la virgola contenuta nel valore del campo $3
.
Un semplice miglioramento se si elaborano dati CSV di questo tipo potrebbe essere quello di rimuovere i doppi apici, se presenti, con del codice di questo tipo:
if (substr($i, 1, 1) == "\"") { len = length($i) $i = substr($i, 2, len - 2) # Ottiene il testo tra doppi apici }
NOTA: Alcuni programmi esportano dei dati CSV che contengono dei ritorni a capo al loro interno in campi rinchiusi tra doppi apici.
gawk
non è in grado di trattare questi dati. Malgrado esista una specifica ufficiale per i dati CSV, non c’è molto da fare; il meccanismo diFPAT
fornisce una soluzione elegante per la maggioranza dei casi, e per gli sviluppatori digawk
ciò può bastare.
Come visto, l’espressione regolare usata per FPAT
richiede
che ogni campo contenga almeno un carattere. Una semplice modifica
(cambiare il primo ‘+’ con ‘*’) permette che siano presenti dei
campi vuoti:
FPAT = "([^,]*)|(\"[^\"]+\")"
Come per FS
, la variabile IGNORECASE
(vedi la sezione Variabili predefinite modificabili per controllare awk
) ha effetto sulla separazione dei
campi con FPAT
.
Se si assegna un valore a FPAT
la divisione in campi non viene
effettuata utilizzando FS
o FIELDWIDTHS
.
Infine, la funzione patsplit()
rende la stessa funzionalità disponibile
per suddividere normali stringhe (vedi la sezione Funzioni di manipolazione di stringhe).
Il formato CSV non ha avuto, per molti anni, una definizione standard formale. RFC 4180 standardizza le pratiche più comuni.
Successivo: Controllare la creazione di campi, Precedente: Dimensione costante, Su: Leggere file [Contenuti][Indice]