developer tip

정렬하지 않고 중복 줄 제거

optionbox 2020. 9. 2. 17:40
반응형

정렬하지 않고 중복 줄 제거


Python에 유틸리티 스크립트가 있습니다.

#!/usr/bin/env python
import sys
unique_lines = []
duplicate_lines = []
for line in sys.stdin:
  if line in unique_lines:
    duplicate_lines.append(line)
  else:
    unique_lines.append(line)
    sys.stdout.write(line)
# optionally do something with duplicate_lines

이 간단한 기능 (안정적인 순서로 정렬 할 필요가없는 고유)은 간단한 UNIX 유틸리티로 사용 가능해야합니다. 그렇지 않습니까? 파이프에 필터 조합일까요?묻는 이유 : 어디서나 파이썬을 실행할 수없는 시스템에서이 기능이 필요합니다.


UNIX Bash 스크립팅 블로그

다음을 제안합니다 .

awk '!x[$0]++'

이 명령은 인쇄 할 줄을 awk에게 알려줍니다. 변수

$0

는 한 줄의 전체 내용을 포함하고 대괄호는 배열 액세스입니다. 따라서 파일의 각 행에 대해 배열의 노드

x

가 증가하고 해당 노드의 내용이

!

이전에 설정 되지 않은 경우 ( ) 행이 인쇄됩니다 .


늦은 답변-방금 이것의 중복을 만났지만 아마도 추가 할 가치가 있습니다 ...@ 1_CR의 답변 뒤에있는 원칙은 줄 번호를 추가 하는

cat -n

대신 사용하여 더 간결하게 작성할 수 있습니다

awk

.

cat -n file_name | sort -uk2 | sort -nk1 | cut -f2-
  • cat -n줄 번호를 앞에 추가하는 데 사용
  • sort -u중복 데이터 제거 사용
  • sort -n앞에 붙인 번호로 정렬하는 데 사용
  • cut줄 번호를 제거하는 데 사용

위의 Michael Hoffman의 솔루션은 짧고 달콤합니다. 더 큰 파일의 경우 awk를 사용하여 인덱스 필드를 추가 한 다음 여러 라운드의 정렬 및 uniq를 사용하는 Schwartzian 변환 접근 방식은 메모리 오버 헤드가 적습니다. 다음 스 니펫은 bash에서 작동합니다.

awk '{print(NR"\t"$0)}' file_name | sort -t$'\t' -k2,2 | uniq --skip-fields 1 | sort -k1,1 -t$'\t' | cut -f2 -d$'\t'

2 개의 파일에서 중복 제거하기 :

awk '!a[$0]++' file1.csv file2.csv

감사합니다 1_CR! 나는 uniq (중복 사본 1 개 남기기)보다는 "uniq -u"(중복을 완전히 제거)가 필요했습니다. awk 및 perl 솔루션은이를 수행하기 위해 실제로 수정할 수 없습니다. 100,000,000 라인 8-)처럼 유니크하기 때문에 더 적은 메모리 사용이 필요할 수도 있습니다. 다른 사람이 필요로하는 경우를 대비하여 명령의 uniq 부분에 "-u"를 입력합니다.

awk '{print(NR"\t"$0)}' file_name | sort -t$'\t' -k2,2 | uniq -u --skip-fields 1 | sort -k1,1 -t$'\t' | cut -f2 -d$'\t'

이제 Rust로 작성된이 작은 도구를 확인할 수 있습니다 :

uq

.입력을 먼저 정렬하지 않고도 고유성 필터링을 수행하므로 연속 스트림에 적용 할 수 있습니다.


파일의 모든 곳이 아닌 다음 줄의 모든 중복을 제거하고 싶었습니다. 그래서 다음을 사용했습니다.

awk '{
  if ($0 != PREVLINE) print $0;
  PREVLINE=$0;
}'

 

uniq

명령 별칭에서 작동도

http://man7.org/linux/man-pages/man1/uniq.1.html

참고 URL :

https://stackoverflow.com/questions/11532157/remove-duplicate-lines-without-sorting

반응형