Я уверен, что у кого-то возникла следующая потребность, как быстро разбить огромный файл .gz по строкам? Базовый текстовый файл имеет 120 миллионов строк. У меня недостаточно места на диске, чтобы разархивировать весь файл сразу, поэтому мне было интересно, знает ли кто-нибудь сценарий bash / perl или инструмент, который может разбить файл (либо .gz, либо внутренний .txt) на файлы строк размером 3x 40 минут , то есть называя это так:
bash splitter.sh hugefile.txt.gz 4000000 1
would get lines 1 to 40 mn
bash splitter.sh hugefile.txt.gz 4000000 2
would get lines 40mn to 80 mn
bash splitter.sh hugefile.txt.gz 4000000 3
would get lines 80mn to 120 mn
Возможно, для решения этой серии будет достаточно, или для gunzip -c потребуется достаточно места для распаковки всего файла (т. Е. Исходной проблемы): gunzip -c greatfile.txt.gz | голова 4000000
Примечание: я не могу получить дополнительный диск.
Благодарность!
Ответы:
Как это сделать лучше всего зависит от того, что вы хотите:
Если вы хотите одну часть файла , ваша идея использовать
gunzip
иhead
правильно. Ты можешь использовать:Это вывело бы первые 4000000 строк на стандартном выходе - вы, вероятно, захотите добавить другой канал, чтобы фактически что-то делать с данными.
Чтобы получить другие части, вы должны использовать комбинацию
head
иtail
, например:чтобы получить второй блок.
Нет, для
gunzip -c
этого не требуется никакого дискового пространства - он все делает в памяти, а затем передает его на стандартный вывод.Если вы хотите создать все детали за один раз , более эффективно создать их все одной командой, потому что тогда входной файл читается только один раз. Одним хорошим решением является использование
split
; подробности смотрите в ответе Джима Макнамара.источник
gzip
не знает о пределе (который происходит от другого процесса). Еслиhead
используется,head
выйдет, когда получит достаточно, и это будет распространяться наgzip
(через SIGPIPE, см. Википедию). Дляtail
этого не возможно, так что да,gzip
будет распаковывать все.чтобы разделить канал, используйте gunzip -c или zcat, чтобы открыть файл
Добавьте выходные спецификации в команду split.
источник
Поскольку вы работаете с потоком (без перемотки), вам нужно использовать форму хвоста '+ N', чтобы получить строки, начиная со строки N и далее.
источник
Я хотел бы рассмотреть возможность использования сплит .
источник
Непосредственно разделить файл .gz на файлы .gz:
Я думаю, это то, что хотел ОП, потому что у него не так много места.
источник
Вот скрипт на python для открытия набора файлов из каталога, при необходимости распаковать их и прочитать их построчно. Он использует только пространство, необходимое в памяти для хранения имен файлов и текущей строки, плюс небольшие накладные расходы.
Команда print line отправит каждую строку в std out, чтобы вы могли перенаправить ее в файл. В качестве альтернативы, если вы дадите нам знать, что вы хотите сделать со строками, я могу добавить это в скрипт python, и вам не нужно будет оставлять куски файла лежащими вокруг.
источник
Вот Perl-программа, которая может использоваться для чтения стандартного ввода и разделения строк, передавая каждую группу в отдельную команду, которая может использовать переменную оболочки $ SPLIT для направления ее в другое место назначения. Для вашего случая он будет вызываться с
zcat hugefile.txt.gz | perl xsplit.pl 40000000 'cat > tmp$SPLIT.txt; do_something tmp$SPLIT.txt; rm tmp$SPLIT.txt'
Извините, обработка в командной строке немного грязная, но вы поняли идею.
источник