| class | title | date | layout | author | author_github | coauthor | coauthor_github | published | tags | |||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
post |
#howto - Gestire i CSV da terminale |
2024-11-09 07:00 |
post |
Davide Galati (in arte PsykeDady) |
PsykeDady |
toolleeo |
toolleeo |
true |
|
A lavoro mi capita di gestire sempre una certa quantità di CSV e similari, talvolta anche di notevoli dimensioni.
Spesso e volentieri, decido di farlo tramite terminale per automatizzare e velocizzare alcune operazioni.
Il comando sort permette di ordinare da linea di comando in maniera veloce e semplice i file di testo, eventualmente indicando anche dei criteri di ordinamento.
ad esempio il comando:
echo "alberto
giovanni
giacomo
aldo
zurli
davide
zio
pera" | sortRestituirà:
alberto
aldo
davide
giacomo
giovanni
pera
zio
zurli
Tuttavia, per applicare il comando ai file CSV, bisogna applicare alcune opzioni al comando.
Le principali opzioni di sort da conoscere per manipolare i CSV sono:
-tquest'opzione serve per impostare il separatore, nel caso dei csv se seguono il formato standard, sarà-t,.-kquest'opzione serve a richiedere uno specifico campo quando c'è un separatore. Usato in coppia con l'opzione-tpermette di ordinare rispetto ad una determinata cella separata con il carattere indicato dat, altrimenti il separatore standard è lo spazio.-gQuest'opzione può essere utilizzata per richiedere l'ordinamento numerico e non quello alfanumerico, utile per le celle numeriche.-rper ordinare al contrario (ordine decrescente).-uelimina le occorrenze doppie, se usato in combo con-k, lo fa tenendo conto della cella selezionata
Supponendo di avere un file CSV come il seguente::
alberto,alberti, 32
giovanni,storti, 67
giacomo,poretti, 68
aldo,baglio, 66
zurli,mago, 150
davide,galati, 33
zio,pera, 21
pera,zio, 21Cioè nome,cognome,età.
Supponendo di dover ordinare per cognome si può scrivere:
sort -t, -k2 nomicognomieta.csv Output:
alberto,alberti, 32
aldo,baglio, 66
davide,galati, 33
zurli,mago, 150
zio,pera, 21
giacomo,poretti, 68
giovanni,storti, 67
pera,zio, 21
O per età, dal più grande al più piccolo:
sort -t, -k3 -g -r nomicognomieta.csvChe come risultato:
zurli,mago, 150
giacomo,poretti, 68
giovanni,storti, 67
aldo,baglio, 66
davide,galati, 33
alberto,alberti, 32
zio,pera, 21
pera,zio, 21
Provando ad eliminare le righe con la stessa età:
sort -t, -k3 -g -r -u nomicognomieta.csvChe da come risultato:
zurli,mago, 150
giacomo,poretti, 68
giovanni,storti, 67
aldo,baglio, 66
davide,galati, 33
alberto,alberti, 32
zio,pera, 21
Column serve a mostrare i dati in input in colonne, seguendo una specifica formattazione. Non necessita di troppe opzioni, quelle utili ai CSV sono:
-sche imposta il delimitatore dei campi. Ad esempio-s,legge la virgola come delimitatore.-tche organizza i dati con tabella e allineamento a sinistra.
Supponendo di avere un csv siffatto:
alberto,alberti, 32
giovanni,storti, 67
giacomo,poretti, 68
aldo,baglio, 66
zurli,mago, 150
davide,galati, 33
zio,pera, 21
pera,zio, 21Scrivendo:
column -s, -t < nomicognomieta.csvSi avrà:
alberto alberti 32
giovanni storti 67
giacomo poretti 68
aldo baglio 66
zurli mago 150
davide galati 33
zio pera 21
pera zio 21
Ma se il file contiene molti file resta comunque molto scomodo leggerlo senza poterlo navigare. Potrebbe essere utile appendere il comando less con le seguenti opzioni:
-#che seguito da un numero imposta il numero di spazi tra una cella e un altra. Ad esempio-#2mette due spazi.-Nche serve a mostrare il numero di riga per ogni riga del CSV-Sche fa si che si possa navigare "orizzontalmente" nel csv (questa opzione potrebbe essere di default in molte implementazioni di less)
Scrivendo dunque:
column -s, -t < nomicognomieta.csv| less -#2 -N -SSi potrà navigare in totale comodità il file csv senza alcun problema
Considero awk lo strumento "definitivo" per la modifica di una grande mole di dati, riesce a processare riga per riga. È presente sul sito una guida completa su AWK.
Awk rappresenta anche un ottimo metodo per manipolare i dati su csv. Le cose che si possono fare usandolo sono limitate solo dalla fantasia e non si possono trattare tutte ovviamente, ma vediamo come si può utilizzare per fare un parsing e qualche calcolo.
Innanzitutto per leggere un file csv l'unica opzione da utilizzare è -F seguita dal delimitatore. Ad esempio con F ',' leggeremo i csv separati per virgola.
Supponendo il seguente csv:
alberto,alberti, 32
giovanni,storti, 67
giacomo,poretti, 68
aldo,baglio, 66
zurli,mago, 150
davide,galati, 33
zio,pera, 21
pera,zio, 21Si può ad esempio tirare fuori così l'età media:
awk -F ',' '
{
somma+=$3
}
END{
media=somma/NR
print("eta media",media)
}' nomicognomieta.csvPer trovare il più anziano:
awk -F ',' '
BEGIN {
max=0
maxname=""
}
{
if(max<$3){
maxname=$1
max=$3
}
}
END{
print("il più anziano del gruppo si chiama",maxname,"ed ha",max,"anni")
}' nomicognomieta.csvPurtroppo il formato più utilizzato per tabelle dati è diventato nel tempo quello proprietario di excel. Lo svantaggio di questa tipologia di dati è che oltre ad essere proprietario è anche binario, quindi non facilmente leggibile, questo induce a chiedersi come fare a leggere questi dati al di fuori di piattaforme Microsoft.
Nel tempo son nati molti software (proprietari o meno) in grado di leggere gli excel come Libreoffice, WPS, open office etc... così come molte librerie.
Su linux esiste il software in GTK gnumeric che si può installare tramite i vari package manager, tramite questo si può convertire poi, anche a linea di comando, un excel in csv e processarlo tramite i metodi sopra elencati:
Per installare gnumeric su Ubuntu e derivate scrivere
apt install gnumericPer installare gnumeric su Fedora scrivere
dnf install gnumericPer installare gnumeric su ArchLinux scrivere
pacman -S gnumericPer convertire un excel in csv scrivere:
ssconvert file_excel.xlsx file_excel_convertito.csvUn altro tool utilizzabile è xlsx2csv, scritto in python ed installabile tramite pip:
pip install xlsx2csvOppure tramite pipx se si è su ArchLinux:
pipx install xlsx2csvUtilizzabile poi scrivendo:
xlsx2csv file_excel.xlsx > file_excel_convertito.csvI file CSV sono talvolta piuttosto ostici da utilizzare, principalmente perché il formato presenta molte varianti.
Per esempio, normalmente contengono un header con i nomi delle colonne nella prima riga del file, oppure utilizzano i doppi apici - spesso opzionali - per raggruppare i caratteri di stringhe che contengono i delimitatori.
Per esempio:
ID,Nome,Cognome,Indirizzo
1,Paolo,Rossi,"via Paolo, 3"
2,Marco,Bianchi,via Marco Polo
Queste casistiche si possono pensare di trattare con non banali combinazioni di comandi come sort, head, tail e awk, oltre a gestire il tutto con python.
Per esempio, in casi semplici, il comando
head -n 1 file.csvestrae la prima riga dal file file.csv, che potrebbe corrispondere all'header.
Il condizionale è dovuto al fatto che l'header non è obbligatorio nei file CSV, e potrebbe non essere presente, come nei molti esempi presentati in questo articolo.
Quando il formato di un file CSV si fa complicato, oppure le operazioni da svolgere sono non banali, come ad esempio l'unione di due file diversi utilizzando criteri opportuni, ci si può affidare - sempre dalla linea di comando - a strumenti specifici per i file CSV.
Alcuni esempi sono i seguenti:
- csvkit, una suite di comandi per convertire e manipolare i file CSV.
- csvtk, un singolo programma scritto in linguaggio Go, che mette a disposizione parecchi sotto-comandi per manipolare i file CSV.
- tabview, un programma in Python che usa la libreria
ncursesper la visualizzazione di file CSV da terminale.