Vi'deki yinelenen satırları kaldırıyor musunuz?


123

Uzun bir girdi listesi (her satırda bir tane) içeren bir metin dosyam var. Bunlardan bazıları kopyadır ve kopyaları kaldırmanın mümkün olup olmadığını (ve eğer öyleyse nasıl olduğunu) bilmek istiyorum. Mümkünse bunu vi / vim içinden yapmakla ilgileniyorum.



4
Bu 1 yaşında; bu 10 aydır. Yani, tam tersi.
Sydius

: @Sydius konsensüs şu ana öncelik vermektedir upvote sayımı (ayrıca daha fazla sahip olan) olduğu meta.stackexchange.com/questions/147643/... Ve o kimse :-) Vim söz etmediğini, yineleme değildir
Ciro Santilli郝海东冠状病六四 事件 法轮功

Yanıtlar:


269

Dosyanızı sıralamada sorun yoksa şunları kullanabilirsiniz:

:sort u

6
Bu çok güzel. Teşekkürler!
Shrayas

8
Sıralama kabul edilemezse, :%!uniqdosyayı sıralamadan yalnızca yinelenen girişleri kaldırmak için kullanın .
cryptic0

Komutu kullandığınızda tüm dosya değişir mi? nasıl geri dönüyorsun Dosyayı zaten yanlışlıkla kaydettim ... benim hatam
nilon


25

Bunu dene:

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

Hemen ardından kendisinin bir veya daha fazla kopyasının geldiği herhangi bir satırı arar ve tek bir kopya ile değiştirir.

Denemeden önce dosyanızın bir kopyasını alın. Test edilmedi.


1
@hop Benim için test ettiğiniz için teşekkürler. O sırada vim'e erişimim yoktu.
Sean

2
bu, benim için tüm yinelenen satırları aydınlatıyor, ancak silmiyor, burada bir adımı mı kaçırıyorum?
ak85

Eminim bu aynı "ön ek" e sahip ancak daha uzun olan bir satırı takip eden bir satırı da vurgulayacaktır.
hippietrail

3
Bununla ilgili tek sorun, birden fazla yinelemeniz varsa (aynı satırdan 3 veya daha fazla), tüm kopyalar gidene kadar bunu birçok kez çalıştırmanız gerektiğidir, çünkü bu, bir seferde yalnızca bir dizi kopyayı kaldırır.
horta

2
Bunun bir başka dezavantajı: Yinelenen satırlarınız zaten yan yana olmadığı sürece bu işe yaramaz. Önce sıralama, yan yana olmalarını sağlamanın bir yolu olabilir. Bu noktada, diğer cevaplar muhtemelen daha iyidir.
horta

23

Komut satırından şunu yapın:

sort file | uniq > file.new

1
Bu benim için büyük bir dosya için çok kullanışlıdır. Teşekkürler!
Rafid

1
Büyük dosyamda :sort uasılı olduğu gibi , işe kabul edilen cevabı alamadım . Bu çok hızlı ve mükemmel çalıştı. Teşekkür ederim!
Tgsmith61591

1
'uniq' is not recognized as an internal or external command, operable program or batch file.
hippietrail

1
Evet - Bu tekniği 2.3 GB'lik bir dosyada denedim ve şaşırtıcı derecede hızlıydı.
DanM

@hippietrail Windows PC'de misiniz? Belki cygwin'i kullanabilirsiniz.
12431234123412341234123

8

awk '!x[$0]++' yourfile.txtsırayı korumak istiyorsanız (yani sıralama kabul edilemez). Onu vim'den çağırmak :!için kullanılabilir.


4
Bu çok güzel! Sıralamaya gerek kalmaması tam olarak aradığım şeydi!
Cometsong

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

Windows'ta benim için çalışıyor. Yine de önce satırlar sıralanmalıdır.


1
Bu, öneki olan bir satırı izleyen satırı siler : aaaaardından gelen satırı hatalı olarak aaaabbsiler aaaa.
hippietrail

5

Yukarıdaki cevaplardan ikisini birleştirirdim:

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

1G
!Gsort
1G
!Guniq

Kaç tane yinelenen satırın kaldırıldığını görmekle ilgileniyorsanız, arabelleğinizde bulunan satırların sayısını kontrol etmek için önce ve sonra control-G'yi kullanın.


1
'uniq' is not recognized as an internal or external command, operable program or batch file.
hippietrail

3

Görsel çizgi modunda ( Shift+ v) çizgileri seçin , ardından :!uniq. Bu yalnızca birbiri ardına gelen kopyaları yakalayacaktır.


1
Bunun yalnızca uniq programının kurulu olduğu bilgisayarlarda çalışacağını unutmayın, örn. Linux, Mac, Freebsd vb
anteatersa

Sıralamaya ihtiyacı olmayanlar için en iyi cevap bu olacaktır. Windows kullanıcısıysanız, Cygwin veya MSYS'yi denemeyi düşünün.
fx-kirin

1

Uniq'in VimL'de nasıl uygulanabileceğiyle ilgili olarak, sürdürdüğüm bir eklentide Uniq'i arayın . Vim e-posta listesinde verilen uygulamayı uygulamanın çeşitli yollarını göreceksiniz.

Aksi takdirde, :sort ugerçekten gitmenin yolu budur.


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

veya

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

bu sizin için cevabım, birden fazla yinelenen satırı kaldırabilir ve yalnızca birini kaldırmayabilir!


0

Kullanırdım !}uniq, ancak bu yalnızca boş satır yoksa işe yarar.

Bir dosya kullanımda her satır için: :1,$!uniq.


0

Bu sürüm yalnızca bitişik olan yinelenen satırları kaldırır. Demek istediğim, sadece ardışık tekrarlanan satırları siler. Verilen haritayı kullanarak işlev, boş satırlarla karışıklık yaratır. Ancak, REGEX'i satır başlangıcına uyacak şekilde değiştirirseniz, ^yinelenen boş satırları da kaldırır.

" 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>

0

Vi / vim (çok büyük dosyalar için) kullanmayan alternatif bir yöntem, Linux komut satırından sort ve uniq kullanmaktır:

sort {file-name} | uniq -u

0

Bu, her iki benim için çalışıyor .csvve.txt

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

Açıklama: Komutun ilk bölümü benzersiz satırlar yazdırır ve ikinci bölüm, yani orta oktan sonraki bölüm, ilk bölümün çıktısını kaydetmektir.

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

>

<newFileName>

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.