Разбить большой файл на файлы с заданным количеством строк на основе значения первого столбца

Я намеренно цитирую аналогичный вопрос здесь, хотя я не хотел бы, чтобы в столбце 1 было столько файлов, сколько есть разных значений. Например, из:

A.B|100|20
A.B|101|20
A.X|101|30
A.X|1000|20
B.Y|1|1
B.Y|1|2

Я хотел бы разбить его на x файлов, каждый из которых должен содержать не более 5 строк. В примере я хотел бы 2 файла:

A.B|100|20
A.B|101|20
A.X|101|30
A.X|1000|20

а также

B.Y|1|1
B.Y|1|2

awk -F\| '{print>$1}' file1

Для этого примера я мог легко достичь цели в 2 этапа. Для моего реального файла я хочу разделить большой файл размером около 200 Гб с 10 миллионами уникальных значений в первом столбце. Мне бы хотелось, чтобы в каждом файле было около 1 000 000 строк (т. Е. Гибкий порог). Сделать это в 2 этапа невозможно, так как я не могу позволить себе генерировать миллионы файлов. Любая идея?

1 ответ

Решение

С двойным сканированием файла вы можете сделать

$ awk -F\| -v size=5 'NR==FNR  {a[$1]++; next} 
               FNR==1 || p!=$1 {if(count+a[$1]>=size) {f++; count=0} 
                                else count+=a[$1]; p=$1} 
                               {print > "_file_"f+0}' file{,}

$ head _f*
==> _file_0 <==
A.B|100|20
A.B|101|20
A.X|101|30
A.X|1000|20

==> _file_1 <==
B.Y|1|1
B.Y|1|2

обратите внимание, однако, что если один из уникальных ключей может иметь больше записей, чем желаемая длина файла, неразделение и сохранение максимальной длины файла будут конфликтовать. В этом сценарии я предположил, что неразделение является более важным. Например, для того же изменения входного файла, установите размер =1. Ключи не будут разбиты на отдельные файлы, но их длина будет больше 1.

Другие вопросы по тегам