Comando wc in Linux: contare righe, parole, caratteri e byte
wc conta righe, parole, byte e caratteri di file o dati ricevuti sullo standard input. Senza opzioni mostra, nell’ordine, il numero di caratteri di fine riga, di parole e di byte. Usa -l, -w, -c o -m per selezionare la misura che ti serve.
È utile per contare righe di log, aggregare risultati di ricerca e controllare dati negli script. La distinzione essenziale è che wc -l conta i caratteri di fine riga LF (line feed), mentre -c conta byte e -m caratteri: i tre risultati non sono intercambiabili.
Che cos’è wc?
wc deriva da word count, cioè conteggio delle parole. Se ometti il file, oppure usi - come nome, legge lo standard input fino alla fine del flusso; per questo si combina bene con una pipe. Le statistiche dipendono dai dati di ingresso e dalle opzioni scelte, senza modificare i file.
Per GNU wc, una parola è una sequenza non vuota delimitata da caratteri di spazio bianco, oppure dall’inizio o dalla fine dell’input. Sono separatori anche tabulazioni e fine riga: il programma non cerca parole in un dizionario e non separa automaticamente la punteggiatura.
Sintassi e lettura dell’output
Le parentesi quadre indicano elementi facoltativi e non vanno digitate. Negli esempi, prepara i file indicati oppure sostituiscine i nomi con quelli dei tuoi file; esegui i comandi dalla directory che li contiene. Le pipe con printf generano invece direttamente i dati di prova.
wc [opzioni] [file...]
Con un solo file e senza opzioni, l’output contiene fine riga, parole, byte e nome del file. Per esempio:
wc notes.txt
12 48 317 notes.txt
Questo output è illustrativo: descrive un notes.txt con 12 caratteri LF, 48 parole e 317 byte; il tuo file può avere valori diversi. La larghezza dei campi varia, quindi non interpretare le colonne contando gli spazi.
Per vedere solo il valore di cui hai bisogno, specifica l'opzione corrispondente.
wc -l notes.txt
wc -w notes.txt
wc -c notes.txt
Opzioni principali di wc
| Opzione | Misura | Da sapere |
|---|---|---|
-l, --lines |
Caratteri LF | Un’ultima riga senza LF non viene conteggiata. |
-w, --words |
Parole separate da spazio bianco | I separatori dipendono dalla locale e dalle regole GNU. |
-c, --bytes |
Byte | Un carattere UTF-8 può occupare più byte. |
-m, --chars |
Caratteri decodificati | Dipende da locale e codifica; non conta grafemi. |
-L, --max-line-length |
Larghezza massima in colonne | Considera tabulazioni e caratteri larghi. |
--files0-from=file |
Nomi terminati da NUL | Estensione GNU; evita ambiguità nei nomi dei file. |
Puoi combinare le opzioni. L’ordine dei campi è fisso, indipendentemente dall’ordine delle opzioni: fine riga, parole, caratteri, byte e larghezza massima delle righe, limitatamente ai valori richiesti. Le definizioni e le estensioni GNU sono nella sezione wc del manuale GNU Coreutils, nel sorgente ufficiale.
Contare correttamente le righe
wc -l conta i caratteri LF
wc -l conta i caratteri LF, non le righe visuali create dall’andata a capo dell’editor. In un file in cui ogni riga termina con LF, il risultato coincide con il numero di righe; un’ultima riga priva di LF non viene conteggiata.
wc -l access.log
Controlla l’ultimo byte: 0a indica LF. In un file vuoto il comando non mostra alcun byte; un file con terminatori CRLF termina comunque con 0a, ma contiene anche il byte CR 0d prima di LF.
tail -c 1 notes.txt | od -An -t x1
Ottenere un numero senza nome del file
Passando il file come argomento ottieni anche il suo nome. Con la ridirezione <, invece, wc riceve lo standard input e restituisce solo il conteggio richiesto, utile per assegnarlo a una variabile:
line_count=$(wc -l < notes.txt)
printf '%s\n' "$line_count"
GNU wc garantisce l’assenza di spazi iniziali quando stampa un solo conteggio. Altre implementazioni possono formattarlo diversamente: negli script portabili verifica anche il formato numerico.
Differenza fra byte e caratteri
-c conta i byte
wc -c conta i byte dell’input, utile per misurare la dimensione dei dati. Per un file normale letto dall’inizio, il risultato corrisponde alla sua dimensione logica, non allo spazio effettivamente allocato sul disco.
wc -c document.txt
stat legge la dimensione dai metadati e può essere comodo quando ti serve solo quel valore; -c qui è un’opzione GNU di stat. Non dedurre però che GNU wc -c debba sempre leggere ogni byte: per file normali può ottimizzare il conteggio sfruttando dimensione e posizione del file. Per pipe e flussi deve arrivare alla fine dell’input.
stat -c '%s' document.txt
-m conta i caratteri secondo la locale
wc -m interpreta i caratteri secondo la locale, cioè le impostazioni linguistiche e di codifica del processo, in particolare LC_CTYPE. In UTF-8 un carattere ASCII occupa un byte, mentre é ne occupa due. I due comandi seguenti, in una locale UTF-8 e con é precomposta, restituiscono rispettivamente 12 byte e 11 caratteri, incluso LF:
printf 'Linux café\n' | wc -c
printf 'Linux café\n' | wc -m
Verifica la locale con locale e la codifica effettiva del file. GNU wc -m non conta gli errori di codifica come caratteri. Inoltre conta caratteri secondo la locale, non i grafemi percepiti dal lettore: una lettera seguita da un accento combinante o un’emoji composta può occupare più caratteri pur apparendo come un unico simbolo.
Come vengono contate le parole?
wc -w conta sequenze non vuote separate da spazio bianco. Spazi ripetuti, tabulazioni e fine riga separano le parole; la punteggiatura attaccata resta nella stessa sequenza. L’esempio restituisce tre parole:
printf 'one two\tthree\n' | wc -w
3
wc -w non esegue analisi morfologica né segmentazione linguistica: per questi scopi servono strumenti dedicati. La locale influisce sui separatori; GNU tratta inoltre alcuni spazi Unicode come separatori anche quando la locale non lo fa, salvo la variabile POSIXLY_CORRECT. Non usare questo conteggio come misura dei token di un modello linguistico.
Conteggi e totali di più file
Risultati per file e riga del totale
Con più file, per impostazione predefinita compare una riga finale di somma, etichettata total nella locale inglese. Anche l’output qui sotto è illustrativo: 120, 135 e 98 LF nei tre file producono un totale di 353.
wc -l january.log february.log march.log
120 january.log
135 february.log
98 march.log
353 total
Controllare il totale con l’opzione GNU --total
Le versioni recenti di GNU wc supportano --total=auto (totale con più file), always (sempre), only (solo conteggi complessivi, senza nomi o etichetta) e never (nessun totale). Per ottenere solo la somma dei tre file:
wc -l --total=only january.log february.log march.log
--total è un’estensione GNU assente nelle versioni meno recenti e in altre implementazioni. Controlla wc --help prima di usarla. Per gli stessi tre file, un’implementazione che la supporta restituirà 353; se non è disponibile, verifica i risultati per file e la riga finale evitando di dipendere da un’etichetta tradotta.
Esempi pratici con le pipe
Contare le righe selezionate da grep
La pipe passa a wc -l le righe selezionate da grep:
grep 'ERROR' app.log | wc -l
Per un singolo file di testo, grep -c 'ERROR' app.log è più diretto. Una riga con più occorrenze conta una volta sola. GNU grep aggiunge LF all’ultima riga selezionata se manca: il conteggio della pipe può quindi includerla, mentre wc -l app.log non la conterebbe. Un errore di lettura di grep può inoltre essere mascherato dal successo di wc nella pipe; negli script distingui nessuna corrispondenza (stato 1 di grep) da un errore (stato 2). La introduzione del manuale GNU grep, nel sorgente ufficiale chiarisce il trattamento del fine riga.
Contare le righe di un CSV
Se la prima riga è l’intestazione e ogni record occupa esattamente una riga terminata da LF, puoi saltarla con tail -n +2 e contare quelle successive:
tail -n +2 data.csv | wc -l
Se un campo CSV contiene un fine riga fra virgolette, un record occupa più righe fisiche. Anche un ultimo record senza LF altera questo conteggio: per ottenere il numero di record in un CSV generico usa un parser CSV, non questa pipe.
Contare nomi di file con caratteri speciali
Un nome di file può contenere spazi o, sui filesystem che lo consentono, persino LF. Separare i nomi con LF rende ambiguo il loro conteggio. GNU find -print0 emette invece un byte NUL dopo ogni nome; tr conserva soltanto quei delimitatori e wc -c li conta:
find ./logs -type f -name '*.log' -print0 | tr -cd '\0' | wc -c
Il risultato è il numero di file normali con nome corrispondente a *.log, cercati ricorsivamente sotto ./logs. Le virgolette sul modello impediscono alla shell di espanderlo prima di find. La directory deve esistere ed essere accessibile; verifica anche eventuali errori di find, perché l’ultimo comando della pipe può riuscire su un elenco incompleto.
Contare i processi in esecuzione
Se GNU/Linux ps supporta --no-headers, puoi contare le righe della lista dei processi escludendo l'intestazione.
ps -e --no-headers | wc -l
È una fotografia del momento, non un valore stabile: il numero può includere i processi usati dalla stessa pipe e dipende dall’implementazione di ps. Questo esempio richiede ps di procps o un’implementazione compatibile; per monitoraggio continuativo usa una raccolta adatta al sistema.
Misurare la riga più larga
wc -L misura la larghezza massima in colonne di visualizzazione, secondo la locale. Tiene conto dei caratteri larghi e di tabulazioni con arresti ogni otto colonne; non conta semplicemente byte o caratteri.
wc -L table.txt
Per esempio, una riga formata da a, un tab e b ha larghezza 9 colonne, perché b segue l’arresto alla colonna 8. Con più file, il valore complessivo di -L è il massimo delle larghezze, non la somma. Non equipararlo alla lunghezza calcolata da awk o al numero di grafemi.
Gestire molti file
Evitare il limite della riga di comando
L’espansione di moltissimi nomi sulla riga di comando può superarne il limite di lunghezza. --files0-from=- legge dallo standard input i nomi terminati da NUL; è un’estensione GNU e in questo caso lo standard input trasporta l’elenco dei nomi, non i contenuti da contare.
find ./logs -type f -name '*.log' -print0 | wc -l --files0-from=-
La pipe mostra i conteggi LF di ciascun file trovato e, con più file, il totale. I nomi con spazi o LF vengono passati senza ambiguità; il formato testuale dell’output può comunque essere scomodo da analizzare se i nomi contengono LF. Non aggiungere contemporaneamente altri nomi come argomenti quando usi --files0-from.
Attenzione ai totali separati di xargs
find ... | xargs wc -l può dividere l’elenco in più invocazioni di wc, ciascuna con il proprio totale; senza delimitatori NUL interpreta inoltre male nomi con spazi o fine riga. Anche usando xargs -0, la suddivisione in più gruppi rimane possibile. In GNU, --files0-from=- consente un’unica aggregazione.
Usare wc negli script della shell
Richiedere solo il conteggio necessario
Non dividere le colonne multiple dell'output wc senza opzioni usando spazi; invece, richiedi solo il valore necessario con -l, -w o -c. Se il nome del file non è necessario, usa la redirezione dell'input.
bytes=$(wc -c < archive.dat)
Distinguere un errore da zero
Un file vuoto produce correttamente 0; un file inesistente o non leggibile produce un errore. In uno script Bash completo, verifica lo stato dell’assegnazione e restituisci uno stato non nullo in caso di fallimento, come nell’esempio seguente. Se lo provi direttamente in una shell interattiva, exit 1 chiude quella shell: salvalo in uno script separato.
if count=$(wc -l < input.txt); then
printf 'lines=%s\n' "$count"
else
printf 'Impossibile leggere input.txt.\n' >&2
exit 1
fi
Errori comuni e precisazioni
wc -l restituisce una riga in meno
È probabile che l'ultima riga non finisca con un carattere di nuova riga. wc -l conta i caratteri di nuova riga, quindi non include l'ultima riga incompleta. Prima di modificare arbitrariamente il formato originale, controlla le regole di output del programma che ha generato il file.
Byte e caratteri multibyte danno valori diversi
-c misura byte, -m caratteri secondo la locale. La differenza è normale in UTF-8: scegli -c per la dimensione logica dei dati e -m per i caratteri decodificati. Per contare i simboli visibili all’utente serve invece una segmentazione in grafemi.
Si possono contare i file con ls?
ls | wc -l può sembrare sufficiente, ma alias, formati di elenco, file nascosti e nomi contenenti LF possono alterare il risultato. Usa find per definire il tipo di file e la profondità; per nomi arbitrari scegli delimitatori NUL.
Domande frequenti
Cosa succede se esegui wc senza opzioni?
Per impostazione predefinita, viene visualizzato il numero di righe, parole e byte in quell'ordine. Se specifichi un file come argomento, anche il nome del file sarà mostrato alla fine.
Qual è il risultato di wc per un file vuoto?
Un file vuoto ha zero fine riga, parole e byte. Un solo LF vale un fine riga e un byte; un terminatore CRLF contiene invece due byte, ma un solo LF.
wc -w conta le parole con precisione in ogni lingua?
wc -w conta le stringhe separate da spazi bianchi; non esegue una segmentazione delle parole sensibile alla lingua. Considera il risultato come un conteggio delimitato da spazi bianchi piuttosto che un conteggio linguistico delle parole.
Posso passare direttamente una directory a wc?
wc non è un comando per contare direttamente le voci della directory. È necessario creare l'elenco dei file desiderati utilizzando comandi come find e poi aggregare i risultati. Se nei nomi dei file possono esserci caratteri speciali, utilizzare i caratteri NUL come separatori invece delle nuove righe.
Riepilogo
Il numero di righe può essere controllato con wc -l, il numero di parole con wc -w, il numero di byte con wc -c e il numero di caratteri con wc -m. L'output senza opzioni mostra righe, parole e byte in ordine, e se vengono specificati più file, vengono mostrati i valori per ciascun file e la somma totale.
Per un risultato corretto, scegli prima cosa misurare: fine riga LF, sequenze separate da spazio bianco, byte, caratteri decodificati o larghezza in colonne. Per orientarti fra gli strumenti correlati, consulta la guida ai comandi Linux essenziali.




