vi에서 중복 행을 제거 하시겠습니까?


123

긴 항목 목록 (각 줄에 하나씩)이 포함 된 텍스트 파일이 있습니다. 이들 중 일부는 중복되며 중복을 제거하는 것이 가능한지 (그리고 그렇다면 어떻게) 알고 싶습니다. 가능한 경우 vi / vim 내에서이 작업을 수행하는 데 관심이 있습니다.



4
이것은 1 년 된 것입니다. 그 하나는 10 개월입니다. 그래서 다른 방법으로.
Sydius

@Sydius 합의는 이제 upvote 수의 우선 순위를 정하는 것입니다 (여러분도 더 많이 가지고 있음) : meta.stackexchange.com/questions/147643/… 그리고 그것들은 중복이 아닙니다. Vim은 언급하지 않습니다 :-)
Ciro Santilli 郝海东 冠状 病六四事件法轮功

답변:


269

파일 정렬에 문제가 없으면 다음을 사용할 수 있습니다.

:sort u

6
너무 아름다워요. 감사!
Shrayas 2015-06-18

8
정렬이 허용되지 않는 경우 :%!uniq파일을 정렬하지 않고 단순히 중복 항목을 제거 하는 데 사용 하십시오.
cryptic0

명령을 사용하면 전체 파일이 변경됩니까? 어떻게 돌아가나요? 나는 이미 ... 내 나쁜 실수로 파일을 저장
nilon


25

이 시도:

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

바로 뒤에 하나 이상의 복사본이 오는 줄을 검색하고 단일 복사본으로 바꿉니다.

시도하기 전에 파일의 사본을 만드십시오. 테스트되지 않았습니다.


1
@hop 나를 위해 그것을 테스트 해 주셔서 감사합니다. 당시에는 vim에 액세스 할 수 없었습니다.
Sean

2
이것은 나를 위해 모든 중복 라인을 강조 표시하지만 삭제하지 않습니다. 여기에 단계가 누락 되었습니까?
ak85

나는 이것이 또한 같은 "접두사"를 가지고 있지만 더 긴 줄이 뒤 따르는 줄을 강조 할 것이라고 확신합니다.
hippietrail 2015-04-29

3
유일한 문제는 중복이 여러 개있는 경우 (3 개 이상의 동일한 라인) 중복이 한 번에 한 세트 만 제거되기 때문에 모든 중복이 사라질 때까지 여러 번 실행해야한다는 것입니다.
horta

2
이것의 또 다른 단점 : 중복 된 선이 이미 서로 옆에 있지 않으면 작동하지 않습니다. 먼저 정렬은 서로 옆에 있는지 확인하는 한 가지 방법입니다. 그 시점에서 다른 답변이 아마도 더 좋습니다.
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.
hippietrail 2015-04-29

1
예-2.3GB 파일에서이 기술을 시도했는데 놀랍도록 빠릅니다.
DanM

@hippietrail Windows PC를 사용하고 계십니까? 아마도 cygwin을 사용할 수 있습니다.
12431234123412341234123

8

awk '!x[$0]++' yourfile.txt순서를 유지하려는 경우 (즉, 정렬이 허용되지 않음). vim에서 호출하기 위해 :!사용할 수 있습니다.


4
이것은 사랑 스럽습니다! 정렬 할 필요가없는 것이 정확히 내가 찾던 것입니다!
Cometsong

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

Windows에서 나를 위해 작동합니다. 하지만 줄을 먼저 정렬해야합니다.


1
이렇게하면 접두사 인 줄 다음 줄 이 삭제됩니다 . aaaa뒤에 오는 줄은 잘못 aaaabb삭제 aaaa됩니다.
hippietrail 2015-04-29

5

위의 두 가지 답변을 결합합니다.

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.
hippietrail 2015-04-29

3

시각적 선 모드 ( Shift+ v)에서 선을 선택한 다음 :!uniq. 그것은 차례로 오는 중복 만 잡을 것입니다.


1
그냥 UNIQ 프로그램을 컴퓨터에이에만 작업을주의해야 설치 즉, 리눅스, 맥, FreeBSD의 등
anteatersa

분류가 필요없는 분들에게 최고의 답변이 될 것입니다. Windows 사용자 인 경우 Cygwin 또는 MSYS를 사용해보십시오.
fx-kirin

1

VimL에서 Uniq를 구현하는 방법에 대해서는 유지 관리하고 있는 플러그인 에서 Uniq를 검색하십시오 . Vim 메일 링리스트에있는 다양한 구현 방법을 볼 수 있습니다.

그렇지 않으면 :sort u실제로 갈 길입니다.


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

또는

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

이것은 당신을위한 내 대답입니다. 여러 중복 줄을 제거하고 하나만 제거 할 수 있습니다!


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>

설명 : 명령의 첫 번째 부분은 고유 한 행을 인쇄하고 두 번째 부분은 즉 가운데 화살표 뒤의 첫 번째 부분의 출력을 저장하는 것입니다.

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

>

<newFileName>

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.