Vai al contenuto
OneKitly

Trovare i duplicati di un elenco senza foglio di calcolo

Pubblicato il 07/08/2026 · 11 min di lettura · Strumenti testo e lingua

Daniel Okonkwo

Daniel OkonkwoSviluppatore front-end e redattore Tech presso OneKitly

Performance web · Formati di file

Verificato su 4 fonti

Vedi il profilo
In breve

duplicate-line-finder confronta righe intere, byte per byte. Per impostazione predefinita il confronto distingue maiuscole e minuscole: Paris, paris e PARIS passati insieme non hanno dato alcun duplicato; attivando «Ignora maiuscole» ne segnala uno, stampato come Paris, la grafia della prima occorrenza. Non taglia: «Paris» sopra «Paris» con uno spazio finale torna senza duplicati, in entrambe le modalità. È la sorpresa più frequente, e vale la pena sapere che lo strumento gemello remove-duplicate-lines taglia invece per impostazione predefinita, e su quello stesso input di due righe ne cancella una. Nessuno dei due sbaglia; rispondono semplicemente a domande diverse, e convivono sul sito. Non applica nemmeno la normalizzazione Unicode: una parola il cui accento sta in un solo punto di codice e la stessa parola il cui accento è una lettera seguita da un segno combinante sono due righe diverse, benché si disegnino identiche — cosa che colpisce in particolare gli elenchi francesi, spagnoli e portoghesi. L'output non è un elenco deduplicato. È l'insieme dei valori che compaiono più di una volta, stampati una volta ciascuno, nell'ordine della loro prima comparsa e con il testo esatto di quella prima comparsa. Se nulla si ripete ottieni un breve messaggio invece di un riquadro vuoto. Le righe vuote contano come tutte le altre, con una stranezza: se l'unico valore ripetuto del tuo elenco è la riga vuota, lo strumento annuncia che non ci sono duplicati, perché il suo output sarebbe una stringa vuota e la stringa vuota fa scattare lo stesso messaggio.

Due righe che sembrano identiche spesso non lo sono. Le maiuscole, uno spazio finale, uno spazio unificatore e due codifiche diverse della stessa lettera accentata sono stati passati nel rilevatore di duplicati, che in tre casi su quattro non ne ha segnalato nessuno.

Cosa restituisce davvero lo strumento

Conta ogni riga, tiene quelle il cui conteggio supera uno, e stampa ciascuna una volta. Sull'input b, a, b, a, c ha restituito b e poi a — in quell'ordine perché b compare per primo, non perché b si ripeta di più. Nulla viene ordinato, nulla viene tolto dal tuo elenco, e il numero di ripetizioni di ciascun valore non è indicato. Se vuoi l'elenco senza le ripetizioni, quello è un altro strumento, remove-duplicate-lines, e conserva la prima occorrenza di ogni valore nella sua posizione originale.

Il testo stampato è la prima occorrenza, parola per parola. Sembra un dettaglio finché non attivi «Ignora maiuscole»: dato Apple, banana, APPLE stampa Apple, né APPLE né apple. Ha deciso che i due sono lo stesso valore, deve mostrartene uno, e mostra quello incontrato per primo. Se il tuo elenco mescola grafie urlate e normali, l'output ti dice quale grafia è arrivata per prima, non quale sia più frequente né quale sia corretta.

Lo spazio finale, e lo strumento gemello che dissente

«Paris» sopra «Paris» con uno spazio finale non ha prodotto duplicati, e «Paris» sopra «spazio Paris» nemmeno. Le due righe differiscono di un carattere, quel carattere è invisibile, e lo strumento non ha alcuna opzione di taglio da attivare. Intanto remove-duplicate-lines porta un interruttore «Taglia le righe» attivo di fabbrica: entrano quelle stesse due righe e ne esce una. Due strumenti della stessa categoria, a una pagina di distanza, che danno risposte opposte sullo stesso input. Entrambi sono difendibili: un rilevatore di duplicati che tagliasse mentirebbe su cosa c'è nel tuo file, e un rimozionatore che non tagliasse ti lascerebbe un elenco che sembra ancora pieno di doppioni.

La conseguenza pratica è un ordine di operazioni. Passa prima trim-lines sull'elenco, poi il rilevatore. Su un input volutamente disordinato — due spazi, alpha, due spazi, poi una riga di sola tabulazione, poi due spazi, beta, uno spazio, poi una riga vuota, poi alpha — il rilevatore non ha segnalato duplicati sul testo grezzo, e ha segnalato alpha sullo stesso testo dopo il passaggio di trim-lines e remove-blank-lines. Nulla dell'elenco è cambiato in un modo che un lettore avrebbe notato. È cambiata la capacità dello strumento di vedere ciò che il lettore vedeva.

Due scritture della stessa parola accentata

Unicode può scrivere una lettera accentata in due modi. O come un punto di codice che porta già l'accento, o come la lettera nuda seguita da un segno combinante separato. Entrambi si disegnano con lo stesso glifo, entrambi sono corretti, e quale ti tocca dipende dalla provenienza del testo: alcuni sistemi operativi e alcune vie di immissione producono la forma decomposta per impostazione predefinita. L'allegato standard Unicode n. 15 definisce le forme di normalizzazione che fanno corrispondere l'una all'altra, e JavaScript le espone tramite un metodo di stringa. duplicate-line-finder non lo chiama.

Così un elenco con la parola «café» scritta una volta per modo è tornato senza duplicati. Le due righe sono visivamente indistinguibili e lunghe quattro punti di codice contro cinque. Poi la stranezza: aggiungi una terza copia nella prima scrittura e lo strumento segnala d'improvviso un duplicato, perché due delle tre ora coincidono esattamente. È questa la forma di fallimento da sorvegliare. Non è che lo strumento non trovi mai duplicati accentati; è che ne trova alcuni, il che rende molto più difficile accorgersi di quelli mancati. Se il tuo elenco è francese, spagnolo, portoghese, tedesco o italiano e i conteggi sembrano un po' bassi, è la prima cosa da provare — e il modo di provarlo è ordinare prima l'elenco: le due scritture finiranno una accanto all'altra e si tradiranno rifiutandosi di sembrare diverse.

«Ignora maiuscole» non è come ripiegare la lingua

L'interruttore mette entrambi i lati in minuscolo con la corrispondenza indipendente dalla lingua fornita da JavaScript. Questo copre i casi ordinari in tutte e sei le nostre lingue, e copre correttamente le lettere accentate: le forme maiuscola e minuscola di una vocale accentata si ripiegano l'una sull'altra. Non fa nulla di più di quanto una lingua specifica vorrebbe. La forma maiuscola tedesca scritta con due lettere e l'eszett non si ripiegano insieme, cosa verificata: un elenco di due righe con la scrittura maiuscola e quella minuscola di una parola tedesca corrente è tornato senza duplicati, perché mettere in minuscolo la forma urlata dà due lettere dove l'altra riga ne ha una.

Il punto generale è che «Ignora maiuscole» risponde a una domanda tipografica, non linguistica. Due righe che un lettore francese chiamerebbe la stessa voce — una con l'accento digitato e una senza — qui non sono duplicati e non lo saranno mai, perché togliere gli accenti è un'altra operazione con un altro strumento. Se è quel confronto che ti serve, togli prima gli accenti da una copia dell'elenco, esegui il rilevatore sulla copia e usa il suo output come elenco di cose da verificare nell'originale.

Una routine che regge

Pulire, poi cercare, poi decidere, poi rimuovere. trim-lines e remove-blank-lines mettono ogni riga in una forma confrontabile. duplicate-line-finder ti dice quali valori si ripetono, senza toccare nulla. Guardi quell'elenco breve e decidi se ogni ripetizione è un vero doppio inserimento o due cose diverse che condividono un nome: lo strumento non può saperlo, ed è il passaggio che la gente salta. Solo allora remove-duplicate-lines passa sull'originale. Farlo in quest'ordine significa non cancellare mai una riga che non hai guardato, cosa che conta quando l'elenco è fatto di riferimenti clienti e non di dati di prova.

Un ultimo dettaglio dalle prove. Entrambi gli strumenti dividono su un avanzamento riga preceduto da un ritorno a capo facoltativo, quindi un elenco salvato su Windows e lo stesso salvato su Mac danno risultati identici: un file CRLF con due copie della lettera a ha segnalato un duplicato, esattamente come la versione semplice. E un a capo finale alla fine del tuo elenco crea un'ultima riga vuota, che viene contata ma, da sola, non viene mai stampata.

Coppie di righe dall'aspetto identico, passate nel rilevatore di duplicati, con ciò che ha realmente segnalato
InputCosa ha segnalatoPerché
Paris, paris, PARIS — impostazioni predefiniteNessun duplicato«Ignora maiuscole» è disattivo di default; le tre righe differiscono
Le stesse tre righe con «Ignora maiuscole»Paris — stampato con la grafia della prima occorrenzaEntrambi i lati sono messi in minuscolo per il confronto, ma il testo originale è conservato per la stampa
Paris, poi Paris seguito da uno spazioNessun duplicato, in entrambe le modalitàLo strumento non taglia mai e non ha opzione di taglio
Le stesse due righe in remove-duplicate-linesEsce una sola rigaQuello strumento ha un interruttore «Taglia le righe» attivo di default
New York con spazio ordinario, poi New York con U+00A0Nessun duplicatoPunti di codice diversi; il confronto è sui caratteri esatti
La parola café due volte, scritta con le due forme UnicodeNessun duplicatoNon viene applicata normalizzazione; una riga ha quattro punti di codice, l'altra cinque
Lo stesso, più una terza copia nella prima formacafé — viene segnalato un duplicatoDue delle tre ora coincidono esattamente, quindi il conteggio arriva a due
Un elenco il cui unico valore ripetuto è la riga vuotaNessun duplicatoL'output sarebbe una stringa vuota, e un output vuoto fa scattare lo stesso messaggio
Trova righe duplicateMostra solo le righe che compaiono più di una volta.Prova lo strumento

Domande frequenti

Il rilevatore dice che non ci sono duplicati ma vedo due righe identiche. Cosa succede?
Tre candidati, in ordine di probabilità. Uno spazio iniziale o finale su una delle due, che lo strumento non taglia. Uno spazio unificatore al posto di uno ordinario da qualche parte all'interno, cosa che accade di continuo nel testo incollato da documenti. Oppure due scritture Unicode diverse della stessa lettera accentata. Provali in quest'ordine: esegui trim-lines sull'elenco e riprova, il che risolve il primo candidato in pochi secondi. Se continua a non trovare nulla e le righe contengono accenti, è il terzo candidato, e ordinare l'elenco metterà le due scritture adiacenti per confrontarle.
Perché esistono sia un rilevatore sia un rimozionatore di duplicati?
Perché i due rispondono a domande diverse e hanno impostazioni predefinite diverse. Il rilevatore segnala ciò che si ripete e non cambia nulla, così guardi prima di tagliare; non taglia, il che ne fa un resoconto fedele di ciò che è letteralmente nel file. Il rimozionatore produce un elenco pulito e taglia di default, il che lo rende tollerante verso la sporcizia invisibile che un incolla porta con sé. Su un elenco di due righe che differiscono solo per uno spazio finale, il rilevatore dice che non c'è nulla da segnalare e il rimozionatore ne cancella una. Non è un bug in nessuno dei due; è il motivo per eseguire prima il rilevatore quando l'elenco conta.
Mi dice quante volte si ripete ciascun valore?
No. Conta internamente, usa il conteggio per decidere se un valore merita di essere stampato, e poi stampa solo il valore. Su b, a, b, a, c ha restituito b e a senza alcun numero, e non c'è opzione per mostrarli. Se ti servono i conteggi, la via pratica è ordinare l'elenco e leggere le serie, oppure usare un contatore di parole o di occorrenze sui valori che già sai ripetersi. Il compito del rilevatore è darti un breve elenco di sospetti, e ci si attiene di proposito.
Tratterà un indirizzo email scritto in due modi diversi come un solo indirizzo?
Solo se attivi «Ignora maiuscole», e dovresti: la metà di dominio di un indirizzo è insensibile alle maiuscole per specifica, quindi la stessa casella scritta in due modi è davvero un solo indirizzo. Con l'interruttore spento, lo strumento non segnala nulla su un elenco di due righe con la scrittura mista e quella minuscola dello stesso indirizzo, cosa verificata direttamente. Vale la pena saperlo prima di deduplicare un'esportazione di contatti, perché un elenco che sembra pulito a 1 200 righe può contenerne due dozzine, e ognuna è una persona che riceve l'invio due volte.
Posso usarlo su un elenco di migliaia di righe?
Sì. Il lavoro è una passata per contare e una per raccogliere, con una tabella hash indicizzata sulla riga, quindi il tempo cresce all'incirca al ritmo del numero di righe e non del suo quadrato: un confronto ingenuo di ogni riga con tutte le altre non sopravvivrebbe a qualche migliaio di righe, e non è ciò che accade qui. Tutto gira nella pagina, sulla tua macchina, senza caricamenti, perciò il tetto pratico è la memoria del tuo browser e non un limite di server. Ciò che ti rallenterà non è lo strumento: è leggere l'output e decidere cosa significhi ogni ripetizione.

Articoli che potrebbero interessarti

Tutte le guide
GuidaPulire un elenco incollato da un foglio di calcolo o da un PDFUn incolla porta con sé caratteri invisibili: spazi unificatori, trattini morbidi, spazi a larghezza zero, tabulazioni e CRLF. Quattro strumenti di pulizia sono stati eseguiti su ciascuno, e usano tre definizioni diverse di spazio.TutorialNumerare le righe di un testo per una revisione a più maniLa numerazione parte da 1 e non si può impostare a 0, l'allineamento usa spazi e non zeri, e lo strumento che li toglie annulla otto degli undici separatori senza toccare l'indentazione. Quello che ancora non sa fare è distinguere i tuoi numeri dai suoi.TutorialPulire un testo disordinato: l'ordine delle operazioni che conta davveroTogliere i tag prima di decodificare le entità, ripulire i bordi prima di deduplicare, comprimere gli spazi per ultimo. Tre ordini eseguiti in Node, una pipeline di nove passaggi nella sequenza giusta e i caratteri invisibili — U+00A0, U+200B, U+FEFF — che sopravvivono a ogni pulizia ingenua.SpiegazioneOrdinare il testo non è una sola operazione: quattro ordini che si dicono tutti alfabeticiOrdine per unità di codice, ordine naturale e collazione per locale eseguiti sulla stessa lista in Node, con gli output stampati. Perché Zebra precede apple, perché item10 precede item9 e perché ä sta accanto ad a in tedesco ma dopo la z in svedese.GuidaConvertire fra formati di elenco senza perdere dati: le regole di virgolettatura che nessuno leggeTrasformare un elenco a capo in un elenco a virgole è banale finché un elemento non contiene una virgola. Le regole di virgolettatura della RFC 4180, perché un campo CSV può contenere un a capo, perché i fogli di calcolo europei usano il punto e virgola, e cosa fa un elemento vuoto all'andata e ritorno — ogni caso eseguito e stampato.TutorialFiltrare righe secondo uno schema, senza riga di comandoQuesto è grep per chi non usa grep, con una differenza importante: la ricerca è una sottostringa letterale, quindi una vera espressione regolare restituisce un riquadro vuoto e nessun errore. Ogni affermazione è stata verificata eseguendo lo strumento.

Strumenti correlati

Tutto quanto segue descrive ciò che questi strumenti fanno oggi, verificato eseguendo le loro stesse trasformazioni sugli input esatti riportati in ogni articolo, e non ciò che una norma imponga a uno strumento di testo. Il trattamento del testo riga per riga non ha un'autorità unica: cosa conta come spazio, se due righe accentate siano o no la stessa riga, e dove finisca un URL dentro una frase sono decisi in modo diverso da ogni programma in cui incollerai del testo. Quando uno strumento sbaglia un caso, lo si dice apertamente invece di aggirarlo. Prima di passare qualsiasi cosa di questo su un elenco che non potrai riesportare, passa su una copia e confronta il numero di righe alle due estremità.

Fonti

Hai notato un errore in questo articolo?