다수의 gzip 파일에서 중복된 항목을 병합, 정렬 및 제거합니다.

다수의 gzip 파일에서 중복된 항목을 병합, 정렬 및 제거합니다.

15개의 서로 다른 gzip 파일을 병합하겠습니다. 각 파일의 크기는 2GB에서 15GB까지 다양하므로 파일 크기가 상대적으로 큽니다. 가장 좋은 방법을 연구했지만 여전히 몇 가지 문제가 있습니다.

요약:

15개의 서로 다른 gzip 파일로 시작하여 gzip 형식의 정렬되고 반복되는 무료 파일로 마무리하고 싶습니다.

대화를 쉽게 하기 위해 파일을 다음과 같이 표시했습니다: file1, file2...file15

sort옵션 과 함께 명령을 사용하겠습니다 -u. sort의 매뉴얼 페이지에 따르면 이는 다음을 의미합니다.

-u, --unique with -c, check for strict ordering; without -c, output only the first of an equal run

그래서 제가 하고 싶은 일은 다음과 같습니다.

sort -u file* > sortedFile

제가 이해한 바로는 중복되지 않고 정렬된 파일이 있을 것입니다. 내가 만든 테스트 파일에 따르면 이것이 사실인 것 같지만 이것이 올바른지 확인하고 싶습니까?

이제 딜레마에 또 다른 문제가 발생합니다.

모든 파일이 gzip 형식이므로 먼저 gzip에서 텍스트 파일로 변환하고 결합한 다음 다시 gzip으로 압축하지 않고도 zcat이나 다른 방법을 사용하여 출력을 파이핑하여 정렬할 수 있는 방법이 있습니까? 이렇게 하면 많은 시간이 절약됩니다. 어떤 의견이라도 감사하겠습니다. 나는 이것에 대한 조언을 찾고 있습니다. 나는 연구를 싫어하거나 내 접근 방식에 집착하지 않습니다. 120GB의 데이터에 대해 이러한 명령을 실행하기 전에 약간의 통찰력이 필요합니다.

고마워요!

답변1

문제는 개별 파일이 정렬되지 않았다는 것입니다. 즉, 그런 것을 사용하는 경우 sort -u file* > sortedFile정렬하려면 모든 파일의 내용을 로드한 다음 정렬해야 합니다. 아마도 120GB 이상의 메모리가 없기 때문에 이것이 비효율적이라고 생각합니다.

먼저 모든 파일을 개별적으로 정렬한 다음 를 사용하여 병합하는 것이 좋습니다 sort -m(이 코드는 테스트되지 않았습니다!).

for f in file*; do
  gzip -dc "$f" | sort > sorted.$f.bak
done
sort -m -u sorted.file*.bak > sortedFile
rm -f sorted.file*.bak

매뉴얼 페이지의 관련 부분을 정렬합니다(예:http://unixhelp.ed.ac.uk/CGI/man-cgi?sort):

-m, --merge 정렬된 파일을 병합하지 않습니다.

고쳐 쓰다: 읽고 나서https://stackoverflow.com/questions/930044/how-could-the-unix-sort-command-sort-a-very-large-file, 어쨌든 sort는 입력을 관리 가능한 덩어리로 분할하기 때문에 원래 명령이 아마도 그만큼 빠르다고 생각합니다. 명령줄은 다음과 같습니다.

 sort <(zcat file1) <(zcat file2) ... <(zcat file15) > sortedFile

이를 통해 기계의 여러 코어를 사용할 수도 있습니다.

관련 정보