Сортировать огромный файл

Я хочу отсортировать огромный файл примерно из 20 миллионов строк:

  • по возрастанию по названию команды и
  • затем по убыванию наивысшего балла.

так что я могу получить самые высокие оценки за команду.

Я хочу быть внимательным к ресурсам системы. Так...

  1. Есть ли способ сделать это, не помещая все данные в хэш / массив в Perl?
  2. Можем ли мы сделать это с помощью утилиты сортировки Unix/Linux?

Если да, то можете ли вы показать, как это сделать?

Мой входной файл будет около 20 миллионов строк в следующем формате

Chicago Bulls|Michael Jordan|38
LA Lakers|Kobe Bryant|32
Chicago Bulls|Steve Kerr|16
LA Lakers|Paul Gasol|20
LA Lakers|Shaquile ONeal|19
Chicago Bulls|Scottie Pippen|23
.
.
.

3 ответа

Решение

Вам не нужно сортировать.

 #!/usr/bin/perl
use warnings; use strict;
my %high_score;

while (<DATA>) {
    chomp;
    my ($team_name, $player, $score) = split(/\|/);
    for ($high_score{$team_name}{$player}) {
        $_ = $score
            unless $_ && $_ > $score
    }
}

for my $team_name (sort keys %high_score) {
    my %team_scores = %{ $high_score{$team_name} };
    my @top_players = sort { $team_scores{$b} <=>  $team_scores{$a} } (keys %team_scores);

    my $n = 0;
    for my $player (@top_players) {
        print "$team_name, $player high score: $team_scores{$player}\n";
        last if ++$n >= 2;
    }
}

__DATA__
Chicago Bulls|Michael Jordan|38
Chicago Bulls|Scottie Pippen|23
Chicago Bulls|Poor Joe|10
Chicago Bulls|Steve Kerr|16
LA Lakers|Kobe Bryant|32
LA Lakers|Paul Gasol|20
LA Lakers|Shaquile ONeal|19

Изменения: (1) обновленные требования (2) s/while/for/

Я не думаю, что вы можете сказать sort сортировать по возрастанию в одном столбце и по убыванию в другом. Тем не менее, вы можете использовать два sorts в трубопроводе с использованием -s опция для стабильной сортировки:

sort -t\| -rnk3 file.in | sort -st\| -k1

Я не знаю, если sort сломается с таким большим файлом, но вы можете попробовать следующую команду. Он разделяет поля по трубе, затем сортирует по первому полю и по третьему полю численно в обратном порядке, (-r), потомок:

sort -t'|' -k1,1 -k3,3nr infile

Это дает:

Chicago Bulls|Michael Jordan|38
Chicago Bulls|Scottie Pippen|23
Chicago Bulls|Steve Kerr|16
LA Lakers|Kobe Bryant|32
LA Lakers|Paul Gasol|20
LA Lakers|Shaquile ONeal|19
Другие вопросы по тегам