Corso Linux / Cercare ed elaborare testo con grep, sort, uniq, cut e wc

Usa grep per selezionare righe corrispondenti a un modello, sort per ordinarle, uniq per raggruppare duplicati adiacenti, cut per estrarre campi separati da un delimitatore e wc per contare righe, parole o byte. I comandi mostrati inviano il risultato all'output standard, senza modificare direttamente il file d'ingresso. Collegandoli nell'ordine appropriato puoi svolgere piccole elaborazioni di testo.

Il collegamento fra comandi tramite pipe è approfondito nella lezione su variabili e flusso di esecuzione della shell, in inglese. Qui confronterai dati noti e conteggi attesi.

Creare un piccolo file di dati

La prova presuppone Bash e gli strumenti GNU, eseguiti come utente normale. Se ~/linux-course-12-practice esiste già, scegli un altro nome e usalo nei primi due comandi. Esegui una riga alla volta: se mkdir fallisce, fermati senza proseguire con la creazione dei dati. La redirezione > può sovrascrivere un file esistente.

mkdir ~/linux-course-12-practice
cd ~/linux-course-12-practice
pwd

Prosegui solo dopo il successo di mkdir e cd e dopo aver verificato il percorso con pwd. Il percorso, da solo, non dimostra che la directory sia appena stata creata. Nella nuova directory, con il nome records.txt ancora libero, prepara cinque record: nome e stato sono separati da due punti, e \n produce un a capo.

printf 'alpha:ready\nbeta:waiting\nalpha:done\ngamma:ready\nbeta:ready\n' > records.txt
cat records.txt

cat deve mostrare, nell'ordine, alpha:ready, beta:waiting, alpha:done, gamma:ready e beta:ready, una voce per riga. Tutti gli esempi seguenti usano questo stesso file; prima di procedere correggi eventuali differenze nella sola copia di prova.

Selezionare righe con grep

grep stampa le righe che corrispondono al modello. Con -n aggiunge il numero della riga nel file d'ingresso.

grep -n 'ready' records.txt

Le corrispondenze sono tre; waiting non contiene ready.

1:alpha:ready
4:gamma:ready
5:beta:ready

Il modello predefinito di GNU grep è un'espressione regolare di base: i caratteri speciali possono avere un significato diverso da quello letterale. Per cercare una stringa fissa usa grep -F. Anche in questo esempio la ricerca seleziona una sottostringa nella riga, non impone che l'intero campo di stato sia uguale al modello.

Con l'uso ordinario mostrato qui, GNU grep termina con stato 0 quando trova corrispondenze, 1 quando non ne trova e 2 per un errore. Un risultato vuoto non significa sempre un errore di esecuzione: leggi anche eventuali diagnostiche e lo stato del comando. Opzioni particolari, come -q, hanno condizioni specifiche descritte nel manuale.

Estrarre campi con cut e contare con wc

cut -d: -f1 usa i due punti come delimitatore e seleziona il primo campo, numerato a partire da 1. Restano quindi i nomi, mantenendo l'ordine dei record:

cut -d: -f1 records.txt
alpha
beta
alpha
gamma
beta

Questa forma di cut gestisce delimitatori semplici: non interpreta campi tra virgolette e ritorni a capo incorporati come un parser CSV. Se una riga non contiene il delimitatore, normalmente viene stampata intera; controlla i dati prima di interpretare ogni risultato come un campo valido.

Per contare le righe del file di prova, usa:

wc -l records.txt

Il risultato indica 5 accanto al nome del file. Più precisamente, wc -l conta i caratteri di nuova riga: qui ce n'è uno dopo ogni record, compreso l'ultimo. Un testo che termina senza a capo può avere una riga visibile che non incrementa questo conteggio.

wc -w conta sequenze non vuote separate da spazi bianchi, non campi delimitati da due punti. wc -c conta byte; GNU wc -m conta caratteri secondo la codifica e il locale in uso. Per testo UTF-8, un carattere accentato può occupare più di un byte. Il numero di caratteri non coincide necessariamente con quello dei simboli visivi o delle colonne sullo schermo.

Collegare sort e uniq nell'ordine giusto

sort ordina le righe. uniq raggruppa soltanto righe uguali adiacenti, quindi per contare insieme nomi separati nell'ingresso occorre prima avvicinarli con l'ordinamento. La pipe | passa l'output standard del comando precedente all'ingresso standard del successivo.

cut -d: -f1 records.txt | sort | uniq -c

Il risultato conta alpha due volte, beta due volte e gamma una volta. Spazi iniziali e ordinamento possono variare con locale e implementazione.

      2 alpha
      2 beta
      1 gamma

Se applichi uniq direttamente ai nomi non ordinati della prova, le due occorrenze di alpha e le due di beta restano separate: non sono consecutive. Se invece ordini i record completi, alpha:ready e alpha:done rimangono diversi. Decidi dunque che cosa rappresenta un duplicato prima di scegliere il campo da estrarre.

sort usa le regole di confronto del locale salvo impostazioni diverse. Quando confronti risultati tra sistemi, verifica le impostazioni di locale e usa condizioni coerenti lungo la pipeline. L'ordine mostrato qui riguarda questi nomi semplici, non stabilisce una regola universale per tutte le lingue.

Scegliere lo strumento e confrontare una variazione

Obiettivo Strumento Condizione essenziale
Selezionare righe corrispondenti grep Distinguere espressione regolare e stringa letterale
Ordinare righe sort Controllare locale e chiave di ordinamento
Raggruppare duplicati o frequenze uniq I valori uguali devono essere adiacenti
Estrarre campi con delimitatori semplici cut Indicare delimitatore e numero del campo
Contare righe, parole o byte wc Scegliere che cosa contare tramite l'opzione

Se il risultato è vuoto o inatteso, esamina prima records.txt con cat, poi esegui separatamente le parti della pipeline. Così puoi individuare se la differenza nasce dal modello, dal delimitatore o dall'ordinamento. Un conteggio finale plausibile non basta a dimostrare che tutti i comandi precedenti siano riusciti.

Ora modifica una sola condizione: aggiungi un record beta ai cinque record iniziali. >> aggiunge in coda, mentre il successivo > ricrea i dati originali. Esegui questa prova soltanto sul records.txt preparato nella directory di questa lezione, senza aggiunte personali da conservare.

printf 'beta:ready\n' >> records.txt
cut -d: -f1 records.txt | sort | uniq -c
wc -l records.txt
printf 'alpha:ready\nbeta:waiting\nalpha:done\ngamma:ready\nbeta:ready\n' > records.txt
cut -d: -f1 records.txt | sort | uniq -c
wc -l records.txt

Dopo l'aggiunta, beta deve passare da 2 a 3 e il totale da 5 a 6 righe; alpha resta 2 e gamma resta 1. Dopo la ricreazione, devono tornare alpha 2, beta 2, gamma 1 e il totale di 5 righe. Ripetere la sola aggiunta più volte aumenta ancora i conteggi: parti sempre dai cinque record attesi per confrontare una singola variazione.

Controlla nuovamente il contenuto con cat records.txt dopo il ripristino. La sovrascrittura è intenzionale per questo file di prova; non applicarla a dati importanti. Puoi conservare la directory per ripetere l'esercizio.

Documentazione ufficiale

Il manuale GNU di grep distribuito da Debian spiega modelli e stati di uscita. I manuali GNU di sort, uniq, cut e wc dettagliano ordinamento, campi e conteggi. Per pipe e redirezioni consulta il manuale GNU di Bash, e verifica con man o --help le opzioni della tua installazione.