여러 파일에서 중복된 줄을 빠르게 제거

여러 파일에서 중복된 줄을 빠르게 제거

각 (데이터) 행이 고유해야 하는 많은 양의 데이터가 있습니다.

폴더에 많은 파일이 있다는 것은 이미 사실입니다. 크기는 약 15GB이고 약 170개의 파일로 나누어져 있으며 총 1,000,000개의 라인이 있습니다. 이 폴더를 이라고 부르겠습니다 foo.

이제 두 번째 폴더( bar)에는 더 많은 데이터가 포함됩니다. 즉, 파일당 하나의 항목만 포함됩니다. 두 파일의 교차 부분이 bar반드시 비어 있을 필요는 없습니다. 각 파일에는 약 15,000개의 라인이 있습니다(그리고 그 안에는 수천 개의 파일이 있습니다 bar).

지금 나는 사용하고 있어요

awk 'NR==FNR{a[$0]=$0;next}!a[$0]' foo/file bar/file > tmp
mv tmp bar/file

모든 파일을 반복 foo하고 bar. foo비어 있으면 루프를 끊습니다 bar/file. 잠금(여러 노드에서)과 병렬 실행(각 노드에서)을 사용하여 병렬화했습니다. 하지만 아직 시간이 오래 걸립니다.

성능 향상의 가능성은 무엇입니까? 에 있는 파일의 이상적인 파일 크기는 얼마입니까 foo? 물론 이는 머신(RAM/CPU/스토리지)에 따라 다르지만 여기서 좋은 경험 법칙은 무엇입니까?

너무 길어요.: 합계에 여러 번 나타날 수 있는 데이터 행을 foo포함하여 고유한 데이터 행을 포함합니다 . bar중복된 항목을 제거하여 병합할 수 있습니다.barfoobarfoo

[고쳐 쓰다]빈 줄 없음[/고쳐 쓰다]

답변1

귀하의 질문을 이해했는지 잘 모르겠지만 귀하의 코드는 다음과 같이 최적화될 수 있습니다.

awk '!x{a[$0];next}; !($0 in a)' foo/file x=1 bar/file > tmp

(빈 줄이나 "0"으로 해석되는 줄에 문제가 있는 것 같습니다.)

파일이 정렬되면 다음을 수행할 수 있습니다.

comm -13 foo/file bar/file > tmp

그렇지 않은 경우(ksh93.zsh 또는 bash 구문):

comm -13  <(sort foo/file) <(sort bar/file) > tmp

(awk 솔루션보다 반드시 빠르지는 않습니다)

또한 특히 GNU awk의 경우 로캘을 C/POSIX로 설정하면 더 나은 성능을 얻을 수 있습니다.

LC_ALL=C awk ...

답변2

크기가 몇 MB에 불과한 파일이 여러 개 있습니다. 다음과 같이 시도해 보았습니다.

sort *.csv | uniq -d 

이렇게 하면 파일에 중복 레코드가 제공되고, 출력을 단일 파일로 리디렉션하여 중복 레코드를 얻을 수 있으며, 삭제를 사용하면 -d모든 고유 레코드가 제공됩니다.

관련 정보