Windows에서 매우 큰(800GB) 텍스트 파일의 내용 정렬

Windows에서 매우 큰(800GB) 텍스트 파일의 내용 정렬

나는텍스트각 줄에 단어가 포함된 파일의 경우 파일 크기는 800GB입니다. 단어를 알파벳순으로 정렬해야합니다.

나는윈도우 종류다음을 사용하는 프로그램:

sort.exe input.txt /o output.txt

오류가 발생합니다.정렬을 완료할 만큼 주 메모리가 부족합니다.

32GB가 있어요따라서 다음을 사용하여 정렬에 10GB의 메모리를 지정하려고 하면:

sort.exe input.txt /o output.txt /M 10000000

나는 얻다:

경고: 지정된 메모리 크기가 사용 가능한 페이징 메모리로 줄어들고 있습니다.

입력 레코드가 최대 길이를 초과했습니다. 더 큰 최대값을 지정하세요.

내 옵션은 무엇입니까?

답변1

내 옵션은 무엇입니까?

노력하다프리웨어 명령줄 정렬 유틸리티 CMsort.

여러 임시 파일을 사용하고 마지막에 병합합니다.

CMsort는 조정된 메모리에 도달할 때까지 입력 파일의 레코드를 읽고 있습니다. 그런 다음 레코드가 정렬되어 임시 파일에 기록됩니다. 이는 모든 기록이 처리될 때까지 반복됩니다. 마지막으로 모든 임시 파일이 출력 파일에 병합됩니다. 사용 가능한 메모리가 충분하면 임시 파일이 기록되지 않으며 병합이 필요하지 않습니다.

한 사용자는 130,000,000바이트의 파일을 정렬했다고 보고했습니다.

일부 코드를 직접 조정하고 싶다면 다음도 있습니다.대용량 텍스트 파일 정렬 - CodeProject- "사용 가능한 메모리를 초과하는 텍스트 파일 크기의 줄 정렬 알고리즘"

답변2

또 다른 옵션은 파일을 데이터베이스에 로드하는 것입니다. 예: MySQL 및 MySQL Workbench.
데이터베이스는 대용량 파일 작업에 완벽한 대상입니다.

입력 파일에 새 줄로 구분된 단어만 포함되어 있으면 그리 어렵지 않습니다.

데이터베이스와 MySQL Workbench를 설치한 후에는 다음 작업을 수행해야 합니다.

먼저 스키마를 만듭니다(인수 값을 늘려 변경할 수 있지만 단어가 255자를 넘지 않는다고 가정합니다).

첫 번째 열 "idwords"는 기본 키입니다.

CREATE SCHEMA `tmp` ;

CREATE TABLE `tmp`.`words` (
  `idwords` INT NOT NULL AUTO_INCREMENT,
  `mywords` VARCHAR(255) NULL,
  PRIMARY KEY (`idwords`));

둘째, 데이터를 가져옵니다.
예를 들어 이것은 모든 단어를 테이블로 가져옵니다. 이 단계를 완료하는 데 시간이 걸릴 수 있습니다. 내 조언은 먼저 더 작은 파일로 테스트를 실행하고 형식이 더 큰 파일과 동일하다고 확신하면(테이블을 자르는 것... 즉, 테이블을 지우고 전체 데이터 세트를 로드하는 것) 것입니다.

LOAD DATA LOCAL INFILE "C:\\words.txt" INTO TABLE tmp.words
LINES TERMINATED BY '\r\n'
(mywords);

이 링크는 로드에 적합한 형식을 얻는 데 도움이 될 수 있습니다. https://dev.mysql.com/doc/refman/5.7/en/load-data.html

예를 들어 첫 번째 줄을 건너뛰어야 한다면 다음을 수행하면 됩니다.

LOAD DATA LOCAL INFILE "H:\\words.txt" INTO TABLE tmp.words
-- FIELDS TERMINATED BY ','
LINES TERMINATED BY '\r\n'
IGNORE 1 LINES
(mywords);

마지막으로 정렬된 파일을 저장합니다. PC에 따라 시간이 걸릴 수도 있습니다.

SELECT tmp.words.mywords
FROM tmp.words
order by tmp.words.mywords asc
INTO OUTFILE 'C:\\sorted_words.csv';

원하는 대로 데이터를 검색할 수도 있습니다.
예를 들어 이것은 오름차순으로 처음 50개의 단어를 제공합니다(0 위치 또는 첫 번째 단어부터 시작).

SELECT tmp.words.mywords
FROM tmp.words
order by tmp.words.mywords asc
LIMIT 0, 50 ;

답변3

sort

순서가 지정된 파일과 순서가 지정되지 않은 파일을 정렬하는 데 사용되는 많은 알고리즘이 있습니다 .1] .
해당 알고리즘은 모두 이미 구현되어 있으므로 이미 테스트된 프로그램을 선택하세요.

~ 안에코어 유틸리티 (Linux에서 사용 가능하지만 Windows에서도 사용 가능 [2]sort ), 멀티 코어 프로세서에서 병렬로 실행할 수 있는 명령이 존재합니다 . 일반적으로 이것으로 충분합니다.

귀하의 파일이너무 거대해split -l병렬 옵션( --parallel)을 사용하여 일부 청크로 파일을 분할( )하고 결과를 정렬하는 처리를 도울 수 있습니다.주문한 덩어리옵션 -m(병합 정렬).
여러 가지 방법 중 하나가 설명되어 있습니다.여기(파일 분할, 단일 청크 주문, 정렬된 청크 병합, 임시 파일 삭제).

노트:

  • Windows 10에는 소위 말하는 것이 있습니다.Linux용 Windows 하위 시스템모든 Linux 예제가 더 자연스럽게 보일 것입니다.
  • 다른 알고리즘을 사용한 정렬에는 정렬할 데이터 항목 수(O(n m ), O(nlogn)...)에 따라 확장되는 실행 시간이 다릅니다.
  • 알고리즘의 효율성은 원본 파일에 이미 존재하는 순서에 따라 달라집니다.
    (예를 들어버블 정렬이미 정렬된 파일(정확히 N)에 대해 가장 빠른 알고리즘이지만 다른 경우에는 효율적이지 않습니다.

답변4

각 줄의 단어가 제한된 어휘(예: 영어)에서 나온 경우 TreeMap 및 기록 개수(여기서 m은 고유 값의 수)를 사용하여 O(n + m log m) 시간에 목록을 정렬할 수 있습니다.

그렇지 않으면 Java 라이브러리를 사용할 수 있습니다대형 분류기. 입력을 정렬된 중간 파일로 분할하고 효율적으로 병합합니다(전체 O(nlogn)). 파일을 정렬하는 방법은 다음과 같습니다.

Sorter.serializerTextUtf8()
      .input(inputFile)
      .output(outputFile)
      .loggerStdOut() // display some progress
      .sort();

나는 무작위로 생성된 16개의 문자 단어로 1.7GB 파일(100m 라인)을 생성하고 위와 같이 142초로 정렬했으며 내가 사용하는 방법의 O(n log n) 계산 복잡성을 기반으로 16개의 문자 단어 중 800GB가 될 것으로 추정합니다. SSD가 장착된 i5 2.3GHz 노트북에서 단일 스레드를 정렬하는 데 약 24시간이 걸립니다.

관련 정보