각 (데이터) 행이 고유해야 하는 많은 양의 데이터가 있습니다.
폴더에 많은 파일이 있다는 것은 이미 사실입니다. 크기는 약 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
중복된 항목을 제거하여 병합할 수 있습니다.bar
foo
bar
foo
[고쳐 쓰다]빈 줄 없음[/고쳐 쓰다]
답변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
모든 고유 레코드가 제공됩니다.