Обработка больших запакованных файлов на Mac и не только
Возникла у меня как-то задача обработать файл с логами. В принципе, задача банальная, я для этого использую Perl и в Linux и в Windows. Но дело в том, что всё это происходит на Mac, файл находится в архиве и он большой. Распакованным, он занимает около 20 ГБ.Какое будет обычное решение? Если бы файл был небольшой, то его можно просто достать из архива и подать на вход скрипта. Но это не так, и место на диске тратить жалко. Для этого есть стандартное решение распаковывать файл в STDOUT и сразу забирать его обработчиком из STDIN (через безымянный pipe, символ »|»). Сказано, сделано. У стандартного в Mac’е распаковщика есть параметры для этого. unzip -p data.zip log.txt | process.pl > result.txt Где, process.pl обработчик логов.После тестирования на небольших файлах всё было отлажено и я перешел к рабочему файлу. Но тут меня ждал сюрприз. Файл обрабатывался моментально, но результат был пустой. Оказалось, что файлы больше 4 ГБ не распаковываются. Ха-ха, и это в 64-разрядной операционке. После гугления оказалось, что да, есть такая проблема. Поговаривают даже, что файл запаковать можно, а распаковать нет. Некоторые программы, которые предлагались, по описанию было хорошие, например, The Unarchiver (http://wakaba.c3.cx/s/apps/unarchiver.html), но имели только графический интерфейс, ну да, конечно, это же Mac. К счастью нашлась еще одна утилита, unar (http://code.google.com/p/theunarchiver/downloads/list) от того же автора, которая умеет работать с командной строкой. Всё классно, но… она умеет распаковывать только в файл, да то только с оригинальным именем. И что же делать? Я уж было решил искать что-то ещё, но вовремя вспомнил про именованные каналы (named pipe), которые позволяет сделать псевдо-файл на диске, который выступает как конвеер, куда одна программа пишет, другая читает и обе считают, что работают с настоящим файлом. То есть план действия получался такой:1. Создаем именованный канал с именем совпадающим с запакованным файлом:
mkfifo log.txt
2. Запускаем обработчик, который будет читать данные их него. Запустим его с символом &, чтобы он работал в фоновом режиме, иначе он будет ждать данные и не освободит терминал, пока не закончит полную обработку:
./process.pl