Domanda

Ho un file di testo che contiene un lungo elenco di voci (una su ogni riga).Alcuni di questi sono duplicati e vorrei sapere se è possibile (e se sì, come) rimuovere eventuali duplicati.Sono interessato a farlo da vi/vim, se possibile.

È stato utile?

Soluzione

Se stai bene ordinando il tuo file, puoi usare:

:sort u

Altri suggerimenti

Prova questo:

:%s/^\(.*\)\(\n\1\)\+$/\1/

Cerca qualsiasi riga immediatamente seguita da una o più copie di se stesso e la sostituisce con una singola copia.

Crea comunque una copia del tuo file prima di provarlo. Non è testato.

Dalla riga di comando basta:

sort file | uniq > file.new

awk '!x[$0]++' yourfile.txt se si desidera preservare l'ordine (ovvero l'ordinamento non è accettabile). Per invocarlo da vim, :! può essere usato.

g/^\(.*\)$\n\1/d

Funziona per me su Windows. Le linee devono essere ordinate per prime però.

Combinerei due delle risposte sopra:

go to head of file
sort the whole file
remove duplicate entries with uniq

1G
!Gsort
1G
!Guniq

Se eri interessato a vedere quante linee duplicate sono state rimosse, usa control-G prima e dopo per verificare il numero di linee presenti nel tuo buffer.

Seleziona le linee in modalità linea visiva ( Maiusc + v ), quindi :!uniq. Ciò catturerà solo i duplicati che si susseguono uno dopo l'altro.

Per quanto riguarda come Uniq può essere implementato in VimL, ​​cerca Uniq in a plugin che sto mantenendo.Vedrai vari modi per implementarlo forniti sulla mailing-list di Vim.

Altrimenti, :sort u è infatti la strada da percorrere.

:%s/^\(.*\)\(\n\1\)\+$/\1/gec

o

:%s/^\(.*\)\(\n\1\)\+$/\1/ge

questa è la mia risposta per te, può rimuovere più righe duplicate e mantieni solo uno non rimuoverlo!

Vorrei usare !}uniq, ma funziona solo se non ci sono righe vuote.

Per ogni riga di un file utilizzare: :1,$!uniq.

Questa versione rimuove solo le righe ripetute contigue. Voglio dire, elimina solo le righe ripetute consecutive. Usando la mappa data la funzione fa confusione con le righe vuote. Ma se cambia REGEX in modo che corrisponda all'inizio della riga ^ rimuoverà anche le righe vuote duplicate.

" function to delete duplicate lines
function! DelDuplicatedLines()
    while getline(".") == getline(line(".") - 1)
        exec 'norm! ddk'
    endwhile
    while getline(".") == getline(line(".") + 1)
        exec 'norm! dd'
    endwhile
endfunction
nnoremap <Leader>d :g/./call DelDuplicatedLines()<CR>

Un metodo alternativo che non usa vi / vim (per file molto grandi), è dalla riga di comando di Linux usa sort e uniq:

sort {file-name} | uniq -u

Questo ha funzionato per me sia per .csv sia per .txt

awk '!seen[$0]++' <filename> > <newFileName>

Spiegazione: La prima parte del comando stampa righe uniche e la seconda parte, ovvero dopo la freccia centrale, consente di salvare l'output della prima parte.

awk '!seen[$0]++' <filename>

>

<newFileName>

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top