Обробка великих запакованих файлів на 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 <log.txt >results.txt &

3. Тепер можна запустити розпаковування:
./unar-D-f data.zip log.txt

Параметр-D не створювати директорію.
-f ігнорувати, якщо файл з таким ім'ям вже існує.
4. Після закінчення роботи видалити іменований канал:
unlink log.txt

Все відмінно, все працює. Природно, що все описане вище можна використовувати і в звичайному Linux'е.

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.