Oggi un comando spesso sottovalutato che trovo comodissimo in un sacco di occasioni. Si scrive cut, come tagliare (e non cat, il gatto che conosciamo per leggere il contenuto dei file, ma come sempre i gatti c’entrano in qualche modo). cut fa un lavoro semplicissimo: preleva determinate porzioni dalle righe di un file. Ragiona per righe, come altri comandi visti sul canale.
Per gli esempi usiamo lista.txt, un file con una lista di nomi, cognomi ed età separati da tabulazioni. Se non ce l’hai, creane uno (il punto della puntata è il comando, non i dati):
printf 'Mario\tRossi\t30\nLuisa\tBianchi\t25\n' > lista.txt
Lo leggiamo con cat:
cat lista.txt
La sintassi
cut vuole delle opzioni e un file su cui lavorare:
cut OPZIONI file
Tagliare per byte E per caratteri
Con -b si estraggono i primi byte di ogni riga. Prendiamo i byte da 1 a 3 di ogni riga:
cut -b 1-3 lista.txt
Qual è la differenza fra byte e caratteri? In certe codifiche un carattere è definito da più byte. cut ha anche un’opzione, -n, che serve a non dividere i caratteri multibyte. Per i primi tre caratteri esiste -c, e con caratteri semplici il risultato è identico:
cut -c 1-3 lista.txt
È una funzione utile soprattutto nei file a larghezza fissa di colonna, perché permette di estrarre in modo programmatico proprio i campi che ci interessano.
Si possono specificare più range separandoli con la virgola. Il primo carattere e poi i caratteri da 3 a 5:
cut -c 1,3-5 lista.txt
L’output è un po’ strano (Mrio, Lisa), ma è esattamente quello che abbiamo chiesto.
Tagliare per campi
cut sa anche ragionare su file con dei delimitatori, cioè divisi in campi. Il delimitatore di default è la tabulazione, e il nostro file è proprio delimitato da tab. Per avere solo il secondo e il terzo campo si usa -f:
cut -f 2,3 lista.txt
Altri delimitatori
E se il file è delimitato da un altro carattere, per esempio da virgole come un CSV? Nessun problema. Creiamo un CSV con cat e tr, vecchia conoscenza, che sostituisce la tabulazione con una virgola:
cat lista.txt | tr '\t' ',' > lista.csv
cat lista.csv
Se lanciamo il comando di prima otteniamo un pasticcio, perché cut non riesce a capire quali sono i campi:
cut -f 2,3 lista.csv
Gli diciamo allora che il delimitatore, con -d, è la virgola:
cut -d , -f 2,3 lista.csv
Il complemento
Come altri comandi, cut supporta il complemento (–complement), che inverte la selezione. Se faccio la stessa richiesta con –complement ottengo soltanto il campo non nominato dall’opzione -f, cioè il primo:
cut -d , --complement -f 2,3 lista.csv
Range aperti
I range possono essere aperti: si omette il primo o il secondo numero per dire “da” oppure “fino a”. Dal secondo campo fino alla fine della riga:
cut -d , -f 2- lista.csv
Dall’inizio della riga fino al secondo campo:
cut -d , -f -2 lista.csv
È comodo quando sai fino a quale colonna vuoi arrivare, o da quale colonna partire, e per il resto ti va bene andare dall’inizio o fino alla fine della riga.
Cambiare il delimitatore in uscita
Si può anche ottenere un output con un delimitatore diverso. Per esempio devo passare un CSV da Linux a Windows, dove il separatore è il punto e virgola. Con –output-delimiter:
cut -d , --output-delimiter=';' -f 1- lista.csv
Il delimitatore dell’output non è più la virgola ma il punto e virgola. Il pignolo noterà che lo stesso CSV di prima, partendo dal file con le tabulazioni, si poteva ottenere con cut anziché con tr:
cut --output-delimiter=, -f 1- lista.txt
Una delle cose che amo di più dei sistemi Linux è proprio questa: non c’è mai un solo modo scolpito nella pietra, lo stesso risultato si ottiene in tantissimi modi. Alcuni più efficienti, ma la scelta è anche questione di stile e di come imposti i problemi.
Link e risorse
- il video su YouTube
- esempi e comandi della puntata su GitHub
- cut — manuale GNU coreutils
- cut(1) — la man page
Sostieni il canale
PER SOSTENERE IL CANALE BASTANO UN LIKE E UN’ISCRIZIONE!
questi link sono affiliati Amazon, acquistando i libri che ti consiglio sostieni il canale!
