2013-08-12 5 views
6

У меня очень большой файл, более 100 ГБ (много миллиардов линий), и я хотел бы как можно быстрее провести двухуровневую сортировку в Unix-системе с ограниченной памятью. Это будет один шаг в большом скрипте perl, поэтому я бы хотел использовать perl, если это возможно.Как эффективно сортировать большой файл на двух уровнях?

Итак, как я могу это сделать? Мои данные выглядят так:

A 129 
B 192 
A 388 
D 148 
D 911 
A 117 

... Но для миллиардов линий. Мне нужно сначала сортировать по букве, а затем по номеру. Было бы проще использовать свой род Unix, как ...

sort -k1,2 myfile 

Или я могу сделать все это в Perl-то? Моя система будет иметь примерно 16 ГБ памяти, но файл составляет около 100 ГБ.

Спасибо за любые предложения!

+0

Все ли цифры 3 цифры? Если нет, то они выровнены по правому краю? Если оба эти условия сохраняются (все 3 цифры или выравнивание по правому краю), вам нужен только одноуровневый текстовый вид. –

+0

@Jim, спасибо за комментарий. Нет, цифры варьируются от 1-100 000 000, и это всего лишь два несмежных столбца более крупной электронной таблицы (данные секвенирования генома) – jake9115

ответ

8

Утилита UNIX sort может обрабатывать большие данные (например, больше, чем ваши рабочие 16 ГБ ОЗУ), создавая временные рабочие файлы на диске.

Таким образом, я бы рекомендовал просто использовать UNIX sort для этого, как вы предложили, ссылаясь на вариант -T tmp_dir, и убедившись, что tmp_dir имеет достаточно места для хранения всех временных рабочих файлов, которые будут созданы там.

Кстати, это обсуждается в previous SO question.

1

UNIX sort является лучшим вариантом для сортировки данных по этой шкале. Я бы рекомендовал использовать для этого быстрый алгоритм сжатия LZO. Обычно он распространяется как lzop. Установите большой буфер сортировки с помощью опции -S. Если у вас есть диск быстрее, чем тогда, когда у вас есть значение по умолчанию /tmp, установите также -T. Кроме того, если вы хотите сортировать по числу, вы должны определить сортировку сортировки в качестве второго поля сортировки. Таким образом, вы должны использовать такую ​​линию для лучшей производительности:

LC_ALL=C sort -S 90% --compress-program=lzop -k1,1 -k2n 
0

У меня была такая же проблема! После поиска много, и так как я не хотел, чтобы зависимость от оболочки (UNIX), чтобы сделать его портативным на окнах я придумал решение ниже:

#!/usr/bin/perl 
use File::Sort qw(sort_file); 
my $src_dic_name = 'C:\STORAGE\PERSONAL\PROJECTS\perl\test.txt'; 
sort_file({k => 1, t=>" ", I => $src_dic_name, o => $src_dic_name.".sorted"}); 

Я знаю, что это старый пост, но его обновление с решением, чтобы его было легко найти.

Documentation here

Смежные вопросы