22

У меня есть текстовый файл со словом в каждой строке, размер файла 800 ГБ. Мне нужно отсортировать слова по алфавиту.

Я попытался с помощью программы сортировки Windows, используя:

sort.exe input.txt /o output.txt

что выдает ошибку: Недостаточно основной памяти для завершения сортировки.

У меня 32 ГБ оперативной памяти, поэтому, когда я пытаюсь указать 10 ГБ памяти для сортировки, используя:

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

Я получил:

Предупреждение: указанный объем памяти уменьшается до доступной памяти подкачки.

Входная запись превышает максимальную длину. Укажите больший максимум.

Какие у меня варианты?

4 ответа4

22

Еще один вариант - загрузить файл в базу данных. Например, 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`));

Во-вторых, импортируйте данные: EG Это импортирует все слова в таблицу (этот шаг может занять некоторое время. Я бы посоветовал сначала запустить тест с файлом небольших слов, и как только вы убедитесь, что формат такой же, как и у большего (укоротите таблицу .. IE очистить его и загрузить полный набор данных).

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);

Наконец сохраните отсортированный файл. Это может занять некоторое время, в зависимости от вашего компьютера.

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

Вы также можете искать данные по своему усмотрению. EG Это даст вам первые 50 слов в порядке возрастания (начиная с 0-го или первого слова).

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

Удачи
Пит

15

Какие у меня варианты?

Попробуйте бесплатную утилиту сортировки командной строки CMSort.

Он использует несколько временных файлов, а затем объединяет их в конце.

CMsort читает записи входного файла, пока не будет достигнута установленная память. Затем записи сортируются и записываются во временный файл. Это будет повторяться до тех пор, пока все записи не будут обработаны. Наконец, все временные файлы объединяются в выходной файл. Если доступной памяти достаточно, временные файлы не записываются и объединение не требуется.

Один пользователь сообщает, что отсортировал файл размером 130 000 000 байт.

Если вы хотите настроить некоторый код самостоятельно, есть также Сортировка огромных текстовых файлов - CodeProject - «Алгоритм сортировки строк в текстовых файлах, размер которых превышает доступную память»

3

sort

Существует много алгоритмов, используемых для сортировки упорядоченных и не упорядоченных файлов [ 1 ].
Поскольку все эти алгоритмы уже реализованы, выберите программу, уже протестированную.

В coreutils (из Linux, но доступно и для Windows [ 2 ]) существует команда sort способная работать параллельно под многоядерными процессорами: обычно этого достаточно.

Если ваш файл настолько велик, вы можете помочь разделению обработки (split -l), файлу в некоторых чанках, возможно, с использованием параметра параллели (--parallel) и сортировке полученных упорядоченных чанков с помощью опции -m (сортировка слиянием)).
Один из многих способов сделать это объясняется здесь (сплит - файл, заказать отдельные куски, сливающихся заказанные куски, удалить временные файлы).

Заметки:

  • В Windows 10 существует так называемая подсистема Windows для Linux, в которой все примеры Linux будут казаться более естественными.
  • Сортировка с использованием разных алгоритмов имеет разное время выполнения, которое масштабируется в зависимости от количества сортируемых записей данных (O (n m), O (nlogn)...).
  • Эффективность алгоритма зависит от порядка, который уже присутствует в исходном файле.
    (Например, пузырьковая сортировка - это самый быстрый алгоритм для уже упорядоченного файла - ровно N, но в других случаях он неэффективен).
0

Чтобы предложить альтернативное решение для Peter H, существует программа q, которая позволяет использовать команды в стиле SQL для текстовых файлов. Команда ниже будет делать то же самое (запускаться из командной строки в том же каталоге, что и файл), без необходимости установки SQL Workbench или создания таблиц.

q "select * from words.txt order by c1"

c1 - сокращение для столбца 1.

Вы можете исключить повторяющиеся слова с

q "select distinct c1 from words.txt order by c1"

и отправить вывод в другой файл

q "select distinct c1 from words.txt order by c1" > sorted.txt

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .