viで重複行を削除しますか?


122

エントリの長いリスト(各行に1つ)を含むテキストファイルがあります。これらの一部は重複しているため、重複を削除することが可能かどうか(可能であれば、方法も)を知りたいのですが。可能であれば、vi / vim内からこれを行うことに興味があります。



4
これは1歳です。それは10ヶ月です。だから、他の方法で。
Sydius

@Sydiusコンセンサスは今(あなたはまた、より多くのを持っている)upvote数を優先することである。meta.stackexchange.com/questions/147643/...そして、それらは1つがVimの:-)言及していないことを、重複していない
チロSantilli郝海东冠状の病六四事件法轮功

回答:


267

ファイルの並べ替えに問題がない場合は、次を使用できます。

:sort u

6
これはとても美しいです。ありがとう!
Shrayas 14年

8
ソートが許容できない場合は:%!uniq、ファイルをソートせずに重複するエントリを削除するために使用します。
cryptic0

コマンドを使用すると、ファイル全体が変更されますか?どうやって戻るの?私はすでに...私の悪いを誤ってファイルを保存した
ニロン


25

これを試して:

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

自分自身の1つ以上のコピーが後に続く任意の行を検索し、1つのコピーに置き換えます。

ただし、試す前にファイルのコピーを作成してください。テストされていません。


1
@ホップ私のためにそれをテストしていただきありがとうございます。当時はvimにアクセスできませんでした。
ショーン、

2
これにより、重複するすべての行が強調表示されますが、削除されません。ここにステップがないのですか?
ak85 2012

これにより、同じ「プレフィックス」を持つ行が続く行が強調表示されますが、それより長くなります。
ヒッピートレイル2015

3
これに関する唯一の問題は、複数の重複(同じ行が3つ以上)がある場合、一度に1セットの重複を削除するだけなので、すべての重複がなくなるまでこれを何度も実行する必要があることです。
horta

2
これのもう1つの欠点:重複した行が既に互いに隣接していない限り、これは機能しません。最初にソートすることは、それらが互いに隣接していることを確認する1つの方法です。その時点で、他の答えはおそらくより良いでしょう。
horta

23

コマンドラインから次のようにしてください:

sort file | uniq > file.new

1
これは、巨大なファイルの場合に非常に便利でした。ありがとう!
Rafid 2014年

1
:sort u大きなファイルにぶら下がっていたため、承認された回答が機能しませんでした。これは非常に迅速かつ完全に機能しました。ありがとうございました!
Tgsmith61591 2015年

1
'uniq' is not recognized as an internal or external command, operable program or batch file.
ヒッピートレイル2015

1
はい-私は2.3 GBのファイルでこの手法を試しましたが、驚くほど速かったです。
DanM

@hippietrailあなたはWindows PCにいますか?多分あなたはcygwinを使うことができます。
12431234123412341234123

8

awk '!x[$0]++' yourfile.txt順序を保持したい場合(つまり、ソートは受け入れられません)。vimから呼び出すために:!使用できます。


4
これは素敵です!ソートする必要がないのはまさに私が探していたものです!
Cometsong 2017年

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

Windowsで動作します。ただし、最初に行をソートする必要があります。


1
:これはそれの接頭辞である行の次の行を削除しますaaaa続いaaaabb削除させていただきますaaaa誤って。
ヒッピートレイル2015

5

上記の2つの答えを組み合わせます。

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

1G
!Gsort
1G
!Guniq

削除された重複行の数を確認したい場合は、前後にcontrol-Gを使用して、バッファーに存在する行数を確認します。


1
'uniq' is not recognized as an internal or external command, operable program or batch file.
ヒッピートレイル2015

3

視覚線モード(Shift+ v)で線を選択し、次に:!uniq。これは、次々に来る重複のみをキャッチします。


1
これは、uniqプログラムがインストールされているコンピューター(Linux、Mac、Freebsdなど)でのみ機能します
anteatersa

これは、ソートを必要としない人への最良の答えになります。また、Windowsユーザーの場合は、CygwinまたはMSYSの使用を検討してください。
fx-kirin 2016年


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

または

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

これはあなたへの私の答えです、それは複数の重複する行を削除することができ、削除せずに1つだけを保つことができます!


0

私は使うだろう !}uniq、これは空白行がない場合にのみ機能します。

ファイルのすべての行で次を使用します:1,$!uniq


0

このバージョンでは、連続している繰り返し行のみが削除されます。つまり、連続する繰り返し行のみを削除します。指定されたマップを使用すると、関数は空白行で混乱を招きます。ただし、REGEXを行頭に一致するように変更すると、^重複した空白行も削除されます。

" 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(非常に大きなファイルの場合)を使用しない別の方法は、Linuxコマンドラインからsortとuniqを使用することです。

sort {file-name} | uniq -u

0

これは、両方のために私のために働いた.csv.txt

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

説明: コマンドの最初の部分は固有の行を印刷し、2番目の部分は中央の矢印の後に最初の部分の出力を保存することです。

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

>

<newFileName>

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.