Вы упоминаете, что у вас есть файл размером 20 ГБ, с потенциально большим количеством разных строк. В худшем случае каждая строка отличается. Это означает, что вам понадобится 20 ГБ памяти, если вы хотите сделать что-то подобное.
awk '{a[$0]++}END{for (i in a) print i, a[i] }'
Так что этот подход не очень полезен. Исходя из вашего ввода, похоже, ваш файл отсортирован по первому столбцу. В этом случае может помочь следующее:
awk '($1 != key) { for(i in a) print i, a[i]; delete a }
{a[$0]++; key = $1}
END { for(i in a) print i, a[i] }' file
Но, опять же, это может работать не так, как ожидалось, поскольку файл может содержать только одну группу, и снова вам может потребоваться 20 ГБ памяти.
Лучший подход - использовать sort
и uniq
. Сортировка GNU разработана так, что она может легко обрабатывать файлы, размер которых намного превышает общий объем памяти в вашей системе. Однако вам может потребоваться добавить несколько дополнительных параметров:
--temporary-directory=tempdir
: Используйте каталог tempdir
для хранения временных файлов, переопределяя переменную окружения TMPDIR
. Если этот параметр указан несколько раз, временные файлы сохраняются во всех указанных каталогах. Если у вас большая сортировка или слияние с привязкой к вводу / выводу, вы часто можете повысить производительность, используя этот параметр для указания каталогов на разных дисках и контроллерах.
Эта опция может потребоваться, так как /tmp
может не вместить достаточно дискового пространства для сортировки 20 ГБ данных
источник: GNU Coreutils Sort Invocation
sort --temporary-directory=/home/user/tempdir bigfile | uniq -c
Чтобы определить, какой подход вам нужно использовать, я бы предложил:
Сначала подсчитайте общее количество записей в группе:
$ cut -d " " -f1 file | uniq -c | sort -n | awk '(NR==1)END{print $0}'
В приведенной выше строке будет напечатана самая маленькая и самая большая группа (при условии, что ваш файл отсортирован по группе)
Получите максимальную длину строки:
$ awk { l=length($0); m=m<l?l:m } END {print m}' file
Если n_max
(самая большая группа) раз l_max
(самая большая длина) порядка вашего общего объема памяти, используйте опцию sort
В противном случае используйте второй вариант.
Никогда не используйте первую опцию для больших файлов.