데이터를 정렬하지 않고 고유 한 결과 만 얻는 방법은 무엇입니까?


40
$ cat data.txt 
aaaaaa
aaaaaa
cccccc
aaaaaa
aaaaaa
bbbbbb
$ cat data.txt | uniq
aaaaaa
cccccc
aaaaaa
bbbbbb
$ cat data.txt | sort | uniq
aaaaaa
bbbbbb
cccccc
$

필자가 필요한 결과 는 원본 파일의 모든 줄표시하여 파일의 원래 순서를 유지하면서 모든 중복 항목 (연속 행뿐만 아니라)을 제거하는 것 입니다.

이 예에서 실제로 찾고 있던 결과는

aaaaaa
cccccc
bbbbbb

이 일반화 된 uniq작업을 일반적으로 어떻게 수행 할 수 있습니까?

답변:


54
perl -ne 'print unless $seen{$_}++' data.txt

또는 쓸모없는 사용이 필요한 경우cat :

cat data.txt | perl -ne 'print unless $seen{$_}++'

awkPerl이없는 시스템을위한 번역은 다음과 같습니다 .

awk '!seen[$0]++' data.txt
cat data.txt | awk '!seen[$0]++'

3
약간 더 짧은 awk 스크립트는{ if (!seen[$0]++) print }
camh

1
@fred, 파일이 정말로 크지 않다면, 두 버전 모두 실행하는 것보다 입력하는 데 시간이 더 걸립니다.
CJM

8
AWK 버전은 알아두면도 단축 할 수있다 if, print:, 괄호, 중괄호를awk '!seen[$0]++'
고든 데이비슨

2
@Legate, 우리가 본 모든 라인을 기록 하는 배열 의 이름입니다 . 당신은 '!LarryWall[$0]++'모든 awk 간호 를 위해 그것을 바꿀 수 있지만, "보여"는 사람들이 프로그램을 더 잘 이해하도록 도와줍니다.
CJM

1
@Sadi, 그것은 실제로 의견이 아니라 질문으로 요청되었을 것입니다. 그러나 해당 파일의 일부 행은 공백으로 끝나고 일부는 그렇지 않습니다. 이 명령은 끝에 공백을 포함하여 전체 행이 중요하다고 간주합니다.
CJM

13

john 에는 다음과 같은 도구가 있습니다 unique.

usr@srv % cat data.txt | unique out
usr@srv % cat out
aaaaaa
cccccc
bbbbbb

단일 명령 줄에서 추가 도구없이 동일한 작업을 수행하는 것은 조금 더 복잡합니다.

usr@srv % cat data.txt | nl | sort -k 2 | uniq -f 1 | sort -n | sed 's/\s*[0-9]\+\s\+//'
aaaaaa
cccccc
bbbbbb

nl줄 앞에 줄 번호를 인쇄하므로 줄 뒤 sort/ uniq뒤에 있으면 줄 의 원래 순서를 복원 할 수 있습니다. sed나중에 줄 번호를 삭제합니다.;)


동일한 리눅스 명령어 조합이 있습니까?
Lazer

7
"데이터를 정렬하지 않고"에서 무엇을 놓쳤습니까?
Totor

@Totor - 참조 menkus ' 응답 비슷한 의견을합니다. @binfalse-두 번째 솔루션이 작동하지 않습니다 (이 간단한 샘플에서는 작동하지만 실제 입력에서는 작동하지 않습니다). 수정하십시오. 예 : 항상 작동해야합니다.nl -ba -nrz data.txt | sort -k2 -u | sort | cut -f2
don_crissti

6

나는 이것을 사용하는 것을 선호한다 :

cat -n data.txt | sort --key=2.1 -b -u | sort -n | cut -c8-

cat -n 줄 번호를 추가하고

sort --key=2.1 -b -u 두 번째 필드 (추가 된 줄 번호 뒤)를 정렬하여 선행 공백을 무시하고 고유 한 줄을 유지합니다.

sort -n 엄격한 숫자 순서로 정렬

cut -c8- 모든 문자를 열 8에서 EOL로 유지 (즉, 포함 된 줄 번호는 생략)


5
> 데이터를 정렬하지 않고 고유 한 결과 만 얻는 방법은 무엇입니까? > 데이터 정렬 필요 없음
Jan Wikholm

7
'데이터를 정렬하지 않아도'은 제목에만 나타납니다. 실제로 필요한 것은 : "파일에서 원래의 문장 순서를 유지하면서 모든 중복 (연속적인 사본뿐만 아니라)을 제거하여 원본 파일의 모든 행을 표시합니다."
menkus

1
@menkus 키는 "파일에서 원래의 문장 순서를 유지하면서"입니다. 이 답변은 그것을 달성하지 못합니다.
Andrew Ferrier

2

Perl에는이라는 함수가 포함 된 모듈을 사용할 수 있습니다 uniq. 따라서 Perl의 배열에로드 된 데이터를 ave하면이 기능을 호출하여 고유하게 만들지 만 여전히 원래 순서를 유지하십시오.

use List::MoreUtils qw(uniq)    
@output = uniq(@output);

이 모듈에 대한 자세한 내용은 여기를 참조하십시오 : List :: MoreUtils


500GB와 같은 대용량 파일을 처리 할 수 ​​있습니까?
Boy
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.