Concatenare più file CSV
Ultimamente ho avuto l’esigenza di unire tantissimi file di testo in formato
.csv
in modo da poterli riutilizzare altrove.
Ogni file era composto da una riga di intestazione e dai dati a seguire. La mia
esigenza era di unirli tutti assieme, mettendo un’unica intestazione con tutti i
dati dopo di essa. Come si possono unire 622 file in questo modo con Linux?
La situazione
Supponiamo che stiamo lavorando col terminale dentro la directory job
e che i
file .csv
siano in una sotto-directory chiamata dati
:
job/
├── dati
│ ├── file-001.csv
│ ├── file-002.csv
│ ├── file-003.csv
│ ├── ...
Ogni file .csv
è composto così:
LOCALITA;DATA;TMEDIA °C;TMIN °C;TMAX °C;...
Roma;1/5/2010;"17";"10";"22";...
Roma;2/5/2010;"17";"13";"21";...
Roma;3/5/2010;"18";"16";"21";...
...
La prima riga è l’intestazione, le successive i dati veri e propri. L’idea è
quella di prelevare la riga di intestazione dal primo file e successivamente di
prelevare tutte le righe da tutti i file, escludendo però la prima riga, che
abbiamo già prelevato e che è identica in ogni file. Per il nostro scopo
possiamo usare head
e tail
, in un unico comando.
Il comando
Il glorioso ed efficiente comando è:
head -n 1 dati/file-001.csv > unito.csv && tail -n+2 -q dati/*.csv >> unito.csv
Vediamolo nel dettaglio. Il comando è composto da due comandi distinti:
head ... && tail ...
Il primo comando (head -n 1
) preleva dal primo file (ma potrebbe essere
qualunque file, visto che tutti hanno la stessa intestazione dati) la riga di
intestazione e la scrive nel file unito.csv
dentro la directory job
,
esternamente quindi alla directory dati
.
Il secondo (tail -n+2
) preleva da tutti file .csv
tutte le righe a partire
dalla seconda e le accoda al file unito.csv
. Il parametro -q
dice a tail
di non scrivere, prima di ogni blocco di testo accodato nel file unito.csv
, la
riga da cui ha prelevato il blocco stesso. Se togliessimo -q
il risultato
sarebbe qualcosa del tipo:
LOCALITA;DATA;TMEDIA °C;TMIN °C;TMAX °C;...
==> dati_meteo_roma/2010_05_Maggio_roma.csv <==
Roma;1/5/2010;"17";"10";"22";...
Roma;2/5/2010;"17";"13";"21";...
Roma;3/5/2010;"18";"16";"21";...
...
==> dati_meteo_roma/2010_06_Giugno_roma.csv <==
Roma;1/6/2010;"18";"13";"23";...
Roma;2/6/2010;"18";"15";"23";...
Roma;3/6/2010;"17";"11";"22";...
...
Con il parametro -q
, invece, i dati saranno posti uno sotto l’altro:
LOCALITA;DATA;TMEDIA °C;TMIN °C;TMAX °C;...
Roma;1/5/2010;"17";"10";"22";...
Roma;2/5/2010;"17";"13";"21";...
Roma;3/5/2010;"18";"16";"21";...
...
Roma;30/5/2010;"22";"16";"27";...
Roma;31/5/2010;"20";"16";"25";...
Roma;1/6/2010;"18";"13";"23";...
Roma;2/6/2010;"18";"15";"23";...
Roma;3/6/2010;"17";"11";"22";...
...
Quanto tempo e lavoro sarebbe stato necessario se avessimo dovuto farlo manualmente?