Ricerca nel sito web

4 Utilizzo essenziale e pratico del comando Cut in Linux


Il comando cut in Linux consente di rimuovere dati su ogni riga di un file. Leggi questo tutorial per sapere come utilizzarlo in modo efficace per elaborare file di testo o dati CSV.

Il comando cut è lo strumento canonico per rimuovere “colonne” da un file di testo. In questo contesto una “colonna” può essere definita come un intervallo di caratteri o byte identificati dalla loro posizione fisica sulla riga, oppure un intervallo di campi delimitati da un separatore.

Ho scritto in precedenza sull'utilizzo dei comandi AWK. In questa guida dettagliata, spiegherò quattro esempi essenziali e pratici di comando cut in Linux che ti aiuteranno alla grande.

4 Esempi pratici di comando Cut in Linux

Se preferisci puoi guardare questo video che spiega gli stessi esempi pratici di comando cut che ho elencato nell'articolo.

1. Lavorare con intervalli di caratteri

Quando richiamato con l'opzione della riga di comando -c, il comando cut rimuoverà gli intervalli di caratteri.

Come qualsiasi altro filtro, il comando cut non modifica il file di input sul posto ma copierà i dati modificati sul suo output standard. È tua responsabilità reindirizzare l'output del comando su un file per salvare il risultato o utilizzare una pipe per inviarlo come input a un altro comando.

Se hai scaricato i file di test di esempio utilizzati nel video sopra, puoi vedere il file di dati BALANCE.txt, proveniente direttamente da un software di contabilità che mia moglie utilizza al lavoro:

sh$ head BALANCE.txt
ACCDOC    ACCDOCDATE    ACCOUNTNUM ACCOUNTLIB              ACCDOCLIB                        DEBIT          CREDIT
4         1012017       623477     TIDE SCHEDULE           ALNEENRE-4701-LOC                00000001615,00
4         1012017       445452     VAT BS/ENC              ALNEENRE-4701-LOC                00000000323,00
4         1012017       4356       PAYABLES                ALNEENRE-4701-LOC                               00000001938,00
5         1012017       623372     ACCOMODATION GUIDE      ALNEENRE-4771-LOC                00000001333,00
5         1012017       445452     VAT BS/ENC              ALNEENRE-4771-LOC                00000000266,60
5         1012017       4356       PAYABLES                ALNEENRE-4771-LOC                               00000001599,60
6         1012017       4356       PAYABLES                FACT FA00006253 - BIT QUIROBEN                  00000001837,20
6         1012017       445452     VAT BS/ENC              FACT FA00006253 - BIT QUIROBEN   00000000306,20
6         1012017       623795     TOURIST GUIDE BOOK      FACT FA00006253 - BIT QUIROBEN   00000001531,00

Questo è un file di testo a larghezza fissa poiché i campi dati sono riempiti con un numero variabile di spazi per garantire che vengano visualizzati come una tabella ben allineata.

Come corollario, una colonna di dati inizia e termina sempre nella stessa posizione del carattere su ciascuna riga. C'è però un piccolo trabocchetto: nonostante il nome, il comando cut in realtà richiede di specificare l'intervallo di dati che si desidera mantenere, non l'intervallo che desideri rimuovere. Quindi, se avessi bisogno solo delle colonne ACCOUNTNUM e ACCOUNTLIB nel file di dati sopra, scriverei che:

sh$ cut -c 25-59 BALANCE.txt | head
ACCOUNTNUM ACCOUNTLIB
623477     TIDE SCHEDULE
445452     VAT BS/ENC
4356       /accountPAYABLES
623372     ACCOMODATION GUIDE
445452     VAT BS/ENC
4356       PAYABLES
4356       PAYABLES
445452     VAT BS/ENC
623795     TOURIST GUIDE BOOK

Cos'è un intervallo?

Come abbiamo appena visto, il comando cut richiede di specificare l'intervallo di dati che vogliamo conservare. Quindi, introduciamo più formalmente cos'è un intervallo: per il comando cut, un intervallo è definito da una posizione iniziale e finale separate da un trattino. Gli intervalli sono in base 1, ovvero il primo elemento della riga è l'elemento numero 1, non 0. Gli intervalli sono inclusivi: l'inizio e la fine verranno conservati nell'output, così come tutti i caratteri tra di loro. È un errore specificare un intervallo la cui posizione finale è precedente (“inferiore”) alla sua posizione iniziale. Come scorciatoia, puoi omettere il valore iniziale o finale come descritto nella tabella seguente:

  • a-b: l'intervallo tra a e b (incluso)

  • a: equivalente all'intervallo a-a

  • -b: equivalente a 1-a

  • b-: equivalente a b-∞

I comandi di taglio consentono di specificare diversi intervalli separandoli con una virgola. Qui ci sono un paio di esempi:

# Keep characters from 1 to 24 (inclusive)
cut -c -24 BALANCE.txt

# Keep characters from 1 to 24 and 36 to 59 (inclusive)
cut -c -24,36-59 BALANCE.txt

# Keep characters from 1 to 24, 36 to 59 and 93 to the end of the line (inclusive)
cut -c -24,36-59,93- BALANCE.txt

Una limitazione (o caratteristica, a seconda di come la vedi) del comando cut è che non riordinerà mai i dati. Pertanto, il comando seguente produrrà esattamente lo stesso risultato del precedente, nonostante gli intervalli siano specificati in un ordine diverso:

cut -c 93-,-24,36-59 BALANCE.txt

Puoi verificarlo facilmente utilizzando il comando diff:

diff -s <(cut -c -24,36-59,93- BALANCE.txt) \
              <(cut -c 93-,-24,36-59 BALANCE.txt)
Files /dev/fd/63 and /dev/fd/62 are identical

Allo stesso modo, il comando cut non duplica mai i dati:

# One might expect that could be a way to repeat
# the first column three times, but no...
cut -c -10,-10,-10 BALANCE.txt | head -5
ACCDOC
4
4
4
5

Vale la pena menzionare che è stata proposta un'opzione -o per eliminare queste due ultime limitazioni, consentendo all'utilità cut di riordinare o duplicare i dati. Ma questo è stato respinto dal comitato POSIX“perché questo tipo di miglioramento non rientra nell'ambito della bozza dello standard IEEE P1003.2b. "

Per quanto mi riguarda, non conosco alcuna versione tagliata che implementi tale proposta come estensione. Ma se lo fai, per favore, condividilo con noi usando la sezione commenti!

2. Lavorare con intervalli di byte

Quando richiamato con l'opzione della riga di comando -b, il comando cut rimuoverà gli intervalli di byte.

A prima vista, non c'è alcuna differenza evidente tra gli intervalli di caratteri e byte:

sh$ diff -s <(cut -b -24,36-59,93- BALANCE.txt) \
              <(cut -c -24,36-59,93- BALANCE.txt)
Files /dev/fd/63 and /dev/fd/62 are identical

Questo perché il mio file di dati di esempio utilizza la codifica dei caratteri US-ASCII ("charset") poiché il comando file -i può indovinarlo correttamente:

sh$ file -i BALANCE.txt
BALANCE.txt: text/plain; charset=us-ascii

In quella codifica dei caratteri, esiste una mappatura uno a uno tra caratteri e byte. Usando un solo byte, puoi teoricamente codificare fino a 256 caratteri diversi (cifre, lettere, segni di punteggiatura, simboli, ... ). In pratica, quel numero è molto più basso poiché le codifiche dei caratteri prevedono alcuni valori speciali (come i 32 o 65 caratteri di controllo generalmente riscontrabile). In ogni caso, anche se potessimo utilizzare l’intero intervallo di byte, ciò sarebbe ben lungi dall’essere sufficiente per memorizzare la varietà della scrittura umana. Quindi, oggi, la mappatura uno a uno tra caratteri e byte è più un'eccezione che la norma ed è quasi sempre sostituita dall'onnipresente codifica multibyte UTF-8. Vediamo ora come il comando cut può gestirlo.

Lavorare con caratteri multibyte

Come ho detto in precedenza, i file di dati di esempio utilizzati come esempio per quell'articolo provengono da un software di contabilità utilizzato da mia moglie. Sembra che abbia aggiornato il software di recente e, successivamente, i file di testo esportati erano leggermente diversi. Ti lascio provare a individuare la differenza da solo:

sh$ head BALANCE-V2.txt
ACCDOC    ACCDOCDATE    ACCOUNTNUM ACCOUNTLIB              ACCDOCLIB                        DEBIT          CREDIT
4         1012017       623477     TIDE SCHEDULE           ALNÉENRE-4701-LOC                00000001615,00
4         1012017       445452     VAT BS/ENC              ALNÉENRE-4701-LOC                00000000323,00
4         1012017       4356       PAYABLES                ALNÉENRE-4701-LOC                               00000001938,00
5         1012017       623372     ACCOMODATION GUIDE      ALNÉENRE-4771-LOC                00000001333,00
5         1012017       445452     VAT BS/ENC              ALNÉENRE-4771-LOC                00000000266,60
5         1012017       4356       PAYABLES                ALNÉENRE-4771-LOC                               00000001599,60
6         1012017       4356       PAYABLES                FACT FA00006253 - BIT QUIROBEN                  00000001837,20
6         1012017       445452     VAT BS/ENC              FACT FA00006253 - BIT QUIROBEN   00000000306,20
6         1012017       623795     TOURIST GUIDE BOOK      FACT FA00006253 - BIT QUIROBEN   00000001531,00

Il titolo di questa sezione potrebbe aiutarti a scoprire cosa è cambiato. Ma, trovato o no, vediamo ora le conseguenze di quel cambiamento:

sh$ cut -c 93-,-24,36-59 BALANCE-V2.txt
ACCDOC    ACCDOCDATE    ACCOUNTLIB              DEBIT          CREDIT
4         1012017       TIDE SCHEDULE            00000001615,00
4         1012017       VAT BS/ENC               00000000323,00
4         1012017       PAYABLES                                00000001938,00
5         1012017       ACCOMODATION GUIDE       00000001333,00
5         1012017       VAT BS/ENC               00000000266,60
5         1012017       PAYABLES                                00000001599,60
6         1012017       PAYABLES                               00000001837,20
6         1012017       VAT BS/ENC              00000000306,20
6         1012017       TOURIST GUIDE BOOK      00000001531,00
19        1012017       SEMINAR FEES            00000000080,00
19        1012017       PAYABLES                               00000000080,00
28        1012017       MAINTENANCE             00000000746,58
28        1012017       VAT BS/ENC              00000000149,32
28        1012017       PAYABLES                               00000000895,90
31        1012017       PAYABLES                                00000000240,00
31        1012017       VAT BS/DEBIT             00000000040,00
31        1012017       ADVERTISEMENTS           00000000200,00
32        1012017       WATER                   00000000202,20
32        1012017       VAT BS/DEBIT            00000000020,22
32        1012017       WATER                   00000000170,24
32        1012017       VAT BS/DEBIT            00000000009,37
32        1012017       PAYABLES                               00000000402,03
34        1012017       RENTAL COSTS            00000000018,00
34        1012017       PAYABLES                               00000000018,00
35        1012017       MISCELLANEOUS CHARGES   00000000015,00
35        1012017       VAT BS/DEBIT            00000000003,00
35        1012017       PAYABLES                               00000000018,00
36        1012017       LANDLINE TELEPHONE        00000000069,14
36        1012017       VAT BS/ENC                00000000013,83

Ho copiato sopra l'output del comando in-extenso quindi dovrebbe essere ovvio che qualcosa è andato storto con l'allineamento delle colonne.

La spiegazione è che il file di dati originale conteneva solo caratteri US-ASCII (simboli, segni di punteggiatura, numeri e lettere latine senza segni diacritici)

Ma se osservi attentamente il file prodotto dopo l'aggiornamento del software, puoi vedere che il nuovo file di dati di esportazione ora conserva le lettere accentate. Ad esempio, la società denominata “ALNÉENRE” ora è scritta correttamente mentre in precedenza veniva esportata come “ALNEENRE” (senza accento)

L'utilità file -i non ha mancato questa modifica poiché ora segnala il file come codificato UTF-8:

sh$ file -i BALANCE-V2.txt
BALANCE-V2.txt: text/plain; charset=utf-8

Per vedere come vengono codificate le lettere accentate in un file UTF-8, possiamo utilizzare l'utilità hexdump che ci permette di guardare direttamente i byte in un file:

# To reduce clutter, let's focus only on the second line of the file
sh$ sed '2!d' BALANCE-V2.txt
4         1012017       623477     TIDE SCHEDULE           ALNÉENRE-4701-LOC                00000001615,00
sh$ sed '2!d' BALANCE-V2.txt  | hexdump -C
00000000  34 20 20 20 20 20 20 20  20 20 31 30 31 32 30 31  |4         101201|
00000010  37 20 20 20 20 20 20 20  36 32 33 34 37 37 20 20  |7       623477  |
00000020  20 20 20 54 49 44 45 20  53 43 48 45 44 55 4c 45  |   TIDE SCHEDULE|
00000030  20 20 20 20 20 20 20 20  20 20 20 41 4c 4e c3 89  |           ALN..|
00000040  45 4e 52 45 2d 34 37 30  31 2d 4c 4f 43 20 20 20  |ENRE-4701-LOC   |
00000050  20 20 20 20 20 20 20 20  20 20 20 20 20 30 30 30  |             000|
00000060  30 30 30 30 31 36 31 35  2c 30 30 20 20 20 20 20  |00001615,00     |
00000070  20 20 20 20 20 20 20 20  20 20 20 0a              |           .|
0000007c

Sulla riga 00000030 dell'output hexdump, dopo una serie di spazi (byte 20), puoi vedere:

  • la lettera A è codificata come byte 41,

  • la lettera L è codificata nel byte 4c,

  • e la lettera N è codificata come byte 4e.

Ma la LETTERA LATINA MAIUSCOLA E CON ACUTO (poiché è il nome ufficiale della lettera É nello standard Unicode) è codificata utilizzando due byte c3 89

Ed ecco il problema: usare il comando cut con intervalli espressi come posizioni di byte funziona bene per le codifiche a lunghezza fissa, ma non per quelle a lunghezza variabile come UTF-8 o Shift JIS. Ciò è chiaramente spiegato nel seguente estratto non normativo dello standard POSIX:

Le versioni precedenti dell'utilità cut funzionavano in un ambiente in cui byte e caratteri erano considerati equivalenti (elaborazione modulo e <tab> in alcune implementazioni). Nel mondo esteso dei caratteri multibyte è stata aggiunta la nuova opzione -b.

Ehi, aspetta un attimo! Non stavo usando l'opzione -b nell'esempio "difettoso" sopra, ma l'opzione -c. Quindi non avrebbe dovuto funzionare?!?

Sì, dovrebbe: è un peccato, ma siamo nel 2018 e nonostante ciò, a partire da GNU Coreutils 8.30, l'implementazione GNU dell'utilità cut non gestisce ancora il multi caratteri -byte correttamente. Per citare la documentazione GNU, l'opzione -c è "Lo stesso di -b per ora, ma l'internazionalizzazione cambierà questo[... ] " — una menzione che è presente da più di 10 anni ormai!

D'altra parte, l'implementazione OpenBSD dell'utilità cut è conforme a POSIX e rispetterà le impostazioni locali correnti per gestire correttamente i caratteri multibyte:

# Ensure subseauent commands will know we are using UTF-8 encoded
# text files
openbsd-6.3$ export LC_CTYPE=en_US.UTF-8

# With the `-c` option, cut works properly with multi-byte characters
openbsd-6.3$ cut -c -24,36-59,93- BALANCE-V2.txt
ACCDOC    ACCDOCDATE    ACCOUNTLIB              DEBIT          CREDIT
4         1012017       TIDE SCHEDULE           00000001615,00
4         1012017       VAT BS/ENC              00000000323,00
4         1012017       PAYABLES                               00000001938,00
5         1012017       ACCOMODATION GUIDE      00000001333,00
5         1012017       VAT BS/ENC              00000000266,60
5         1012017       PAYABLES                               00000001599,60
6         1012017       PAYABLES                               00000001837,20
6         1012017       VAT BS/ENC              00000000306,20
6         1012017       TOURIST GUIDE BOOK      00000001531,00
19        1012017       SEMINAR FEES            00000000080,00
19        1012017       PAYABLES                               00000000080,00
28        1012017       MAINTENANCE             00000000746,58
28        1012017       VAT BS/ENC              00000000149,32
28        1012017       PAYABLES                               00000000895,90
31        1012017       PAYABLES                               00000000240,00
31        1012017       VAT BS/DEBIT            00000000040,00
31        1012017       ADVERTISEMENTS          00000000200,00
32        1012017       WATER                   00000000202,20
32        1012017       VAT BS/DEBIT            00000000020,22
32        1012017       WATER                   00000000170,24
32        1012017       VAT BS/DEBIT            00000000009,37
32        1012017       PAYABLES                               00000000402,03
34        1012017       RENTAL COSTS            00000000018,00
34        1012017       PAYABLES                               00000000018,00
35        1012017       MISCELLANEOUS CHARGES   00000000015,00
35        1012017       VAT BS/DEBIT            00000000003,00
35        1012017       PAYABLES                               00000000018,00
36        1012017       LANDLINE TELEPHONE      00000000069,14
36        1012017       VAT BS/ENC              00000000013,83

Come previsto, quando si utilizza la modalità byte -b invece della modalità carattere -c, l'implementazione cut di OpenBSD si comporta come la versione cut legacy:

openbsd-6.3$ cut -b -24,36-59,93- BALANCE-V2.txt
ACCDOC    ACCDOCDATE    ACCOUNTLIB              DEBIT          CREDIT
4         1012017       TIDE SCHEDULE            00000001615,00
4         1012017       VAT BS/ENC               00000000323,00
4         1012017       PAYABLES                                00000001938,00
5         1012017       ACCOMODATION GUIDE       00000001333,00
5         1012017       VAT BS/ENC               00000000266,60
5         1012017       PAYABLES                                00000001599,60
6         1012017       PAYABLES                               00000001837,20
6         1012017       VAT BS/ENC              00000000306,20
6         1012017       TOURIST GUIDE BOOK      00000001531,00
19        1012017       SEMINAR FEES            00000000080,00
19        1012017       PAYABLES                               00000000080,00
28        1012017       MAINTENANCE             00000000746,58
28        1012017       VAT BS/ENC              00000000149,32
28        1012017       PAYABLES                               00000000895,90
31        1012017       PAYABLES                                00000000240,00
31        1012017       VAT BS/DEBIT             00000000040,00
31        1012017       ADVERTISEMENTS           00000000200,00
32        1012017       WATER                   00000000202,20
32        1012017       VAT BS/DEBIT            00000000020,22
32        1012017       WATER                   00000000170,24
32        1012017       VAT BS/DEBIT            00000000009,37
32        1012017       PAYABLES                               00000000402,03
34        1012017       RENTAL COSTS            00000000018,00
34        1012017       PAYABLES                               00000000018,00
35        1012017       MISCELLANEOUS CHARGES   00000000015,00
35        1012017       VAT BS/DEBIT            00000000003,00
35        1012017       PAYABLES                               00000000018,00
36        1012017       LANDLINE TELEPHONE        00000000069,14
36        1012017       VAT BS/ENC                00000000013,83

3. Lavorare con i campi

In un certo senso, lavorare con i campi in un file di testo delimitato è più semplice per l'utilità cut, poiché dovrà solo individuare i delimitatori di campo (un byte) su ogni riga, copiando poi alla lettera il contenuto del campo all'output senza preoccuparsi di eventuali problemi di codifica.

Ecco un esempio di file di testo delimitato:

sh$ head BALANCE.csv
ACCDOC;ACCDOCDATE;ACCOUNTNUM;ACCOUNTLIB;ACCDOCLIB;DEBIT;CREDIT
4;1012017;623477;TIDE SCHEDULE;ALNEENRE-4701-LOC;00000001615,00;
4;1012017;445452;VAT BS/ENC;ALNEENRE-4701-LOC;00000000323,00;
4;1012017;4356;PAYABLES;ALNEENRE-4701-LOC;;00000001938,00
5;1012017;623372;ACCOMODATION GUIDE;ALNEENRE-4771-LOC;00000001333,00;
5;1012017;445452;VAT BS/ENC;ALNEENRE-4771-LOC;00000000266,60;
5;1012017;4356;PAYABLES;ALNEENRE-4771-LOC;;00000001599,60
6;1012017;4356;PAYABLES;FACT FA00006253 - BIT QUIROBEN;;00000001837,20
6;1012017;445452;VAT BS/ENC;FACT FA00006253 - BIT QUIROBEN;00000000306,20;
6;1012017;623795;TOURIST GUIDE BOOK;FACT FA00006253 - BIT QUIROBEN;00000001531,00;

Potresti conoscere il formato file come CSV (per valori separati da virgole), anche se il separatore di campo non è sempre una virgola. Ad esempio, il punto e virgola (;) viene spesso utilizzato come separatore di campo ed è spesso la scelta predefinita quando si esportano dati come "CSV" nei paesi che già utilizzano la virgola come separatore decimale ( come facciamo in Francia - da qui la scelta di quel carattere nel mio file di esempio). Un'altra variante popolare utilizza un carattere di tabulazione come separatore di campo, producendo quello che a volte viene chiamato file di valori separati da tabulazione. Infine, nel mondo Unix e Linux, i due punti (:) sono un altro separatore di campo relativamente comune che potresti trovare, ad esempio, nello standard /etc/passwd e File /etc/group.

Quando utilizzi un formato di file di testo delimitato, fornisci al comando cut l'intervallo di campi da mantenere utilizzando l'opzione -f e devi specificare il delimitatore utilizzando -d opzione (senza l'opzione -d, l'utilità di taglio utilizza per impostazione predefinita un carattere di tabulazione per il separatore):

sh$ cut -f 5- -d';' BALANCE.csv | head
ACCDOCLIB;DEBIT;CREDIT
ALNEENRE-4701-LOC;00000001615,00;
ALNEENRE-4701-LOC;00000000323,00;
ALNEENRE-4701-LOC;;00000001938,00
ALNEENRE-4771-LOC;00000001333,00;
ALNEENRE-4771-LOC;00000000266,60;
ALNEENRE-4771-LOC;;00000001599,60
FACT FA00006253 - BIT QUIROBEN;;00000001837,20
FACT FA00006253 - BIT QUIROBEN;00000000306,20;
FACT FA00006253 - BIT QUIROBEN;00000001531,00;

Gestione delle righe che non contengono il delimitatore

Ma cosa succede se qualche riga nel file di input non contiene il delimitatore? È forte la tentazione di immaginarlo come una riga contenente solo il primo campo. Ma questo non fa l'utilità cut.

Per impostazione predefinita, quando si utilizza l'opzione -f, l'utilità cut restituirà sempre testualmente una riga che non contiene il delimitatore (probabilmente presupponendo che si tratti di una riga non di dati come un'intestazione o un commento di qualche tipo ):

sh$ (echo "# 2018-03 BALANCE"; cat BALANCE.csv) > BALANCE-WITH-HEADER.csv

sh$ cut -f 6,7 -d';' BALANCE-WITH-HEADER.csv | head -5
# 2018-03 BALANCE
DEBIT;CREDIT
00000001615,00;
00000000323,00;
;00000001938,00

Usando l'opzione -s, puoi invertire questo comportamento, quindi cut ignorerà sempre tale riga:

sh$ cut -s -f 6,7 -d';' BALANCE-WITH-HEADER.csv | head -5
DEBIT;CREDIT
00000001615,00;
00000000323,00;
;00000001938,00
00000001333,00;

Se hai voglia di hacker, puoi sfruttare questa funzionalità come un modo relativamente oscuro per mantenere solo le righe contenenti un determinato carattere:

# Keep lines containing a `e`
sh$ printf "%s\n" {mighty,bold,great}-{condor,monkey,bear} | cut -s -f 1- -d'e'

Modifica del delimitatore di output

Come estensione, l'implementazione GNU di cut consente di utilizzare un diverso separatore di campo per l'output utilizzando l'opzione --output-delimiter:

sh$ cut -f 5,6- -d';' --output-delimiter="*" BALANCE.csv | head
ACCDOCLIB*DEBIT*CREDIT
ALNEENRE-4701-LOC*00000001615,00*
ALNEENRE-4701-LOC*00000000323,00*
ALNEENRE-4701-LOC**00000001938,00
ALNEENRE-4771-LOC*00000001333,00*
ALNEENRE-4771-LOC*00000000266,60*
ALNEENRE-4771-LOC**00000001599,60
FACT FA00006253 - BIT QUIROBEN**00000001837,20
FACT FA00006253 - BIT QUIROBEN*00000000306,20*
FACT FA00006253 - BIT QUIROBEN*00000001531,00*

Si noti, in tal caso, che vengono sostituite tutte le occorrenze del separatore di campo e non solo quelle al limite degli intervalli specificati negli argomenti della riga di comando.

4. Estensioni GNU non POSIX

Parlando di estensioni GNU non POSIX, un paio di esse possono essere particolarmente utili. Vale la pena ricordare che le seguenti estensioni funzionano altrettanto bene con byte, caratteri (per cosa significa nell'attuale implementazione GNU) o intervalli di campi:--complement

Pensa a questa opzione come al punto esclamativo in un indirizzo sed (!); invece di mantenere i dati corrispondenti all'intervallo specificato, cut manterrà i dati NON corrispondenti all'intervallo

# Keep only field 5
sh$ cut -f 5 -d';' BALANCE.csv |head -3
ACCDOCLIB
ALNEENRE-4701-LOC
ALNEENRE-4701-LOC

# Keep all but field 5
sh$ cut --complement -f 5 -d';' BALANCE.csv |head -3
ACCDOC;ACCDOCDATE;ACCOUNTNUM;ACCOUNTLIB;DEBIT;CREDIT
4;1012017;623477;TIDE SCHEDULE;00000001615,00;
4;1012017;445452;VAT BS/ENC;00000000323,00;

--terminato con zero (-z)

utilizzare il carattere NUL come terminatore di riga anziché il carattere di nuova riga. L'opzione -z è particolarmente utile quando i tuoi dati possono contenere caratteri di nuova riga incorporati, come quando lavori con i nomi di file (poiché la nuova riga è un carattere valido in un nome di file, ma NUL non lo è).

Per mostrarti come funziona l'opzione -z, facciamo un piccolo esperimento. Per prima cosa creeremo un file il cui nome contiene nuove righe incorporate:

bash$ touch

Supponiamo ora di voler visualizzare i primi 5 caratteri di ciascun nome di file *.txt. Una soluzione ingenua fallirà miseramente qui:

sh$ ls -1 *.txt | cut -c 1-5
BALAN
BALAN
EMPTY
FILE
WITH
NAME.

Potresti aver già letto che ls è stato progettato per il consumo umano e utilizzarlo in una pipeline di comandi è un anti-pattern (lo è infatti). Quindi usiamo invece il comando find:

sh$ find . -name '*.txt' -printf "%f\n" | cut -c 1-5
BALAN
EMPTY
FILE
WITH
NAME.
BALAN

e ... che ha prodotto fondamentalmente lo stesso risultato errato di prima (sebbene in un ordine diverso perché ls ordina implicitamente i nomi dei file, cosa che il comando find non fa).

Il problema è che in entrambi i casi il comando cut non può fare la distinzione tra un carattere di nuova riga che fa parte di un campo dati (il nome del file) e un carattere di nuova riga utilizzato come indicatore di fine record. Ma, utilizzando il byte NUL (\0) come terminatore di riga si elimina la confusione in modo da poter finalmente ottenere il risultato atteso:

# I was told (?) some old versions of tr require using \000 instead of \0
# to denote the NUL character (let me know if you needed that change!)
sh$ find . -name '*.txt' -printf "%f\0" | cut -z -c 1-5| tr '\0' '\n'
BALAN
EMPTY
BALAN

Con quest'ultimo esempio ci stiamo allontanando dal nocciolo di questo articolo, ovvero il comando cut. Quindi, ti lascerò provare a capire da solo il significato del strano "%f\0" dopo l'argomento printf del comando find o perché ho usato il comando tr alla fine della pipeline .

Si può fare molto di più con il comando Taglia

Ho appena mostrato l'utilizzo più comune e, a mio avviso, più essenziale del comando Taglia. Puoi applicare il comando in modi ancora più pratici. Dipende dal tuo ragionamento logico e dalla tua immaginazione.

Non esitare a utilizzare la sezione commenti qui sotto per pubblicare i tuoi risultati. E, come sempre, se ti piace questo articolo, non dimenticare di condividerlo sui tuoi siti e social media preferiti!

Articoli correlati: