19

У меня есть диск на 100 ГБ, который имеет файл на 95 ГБ. Мне нужно освободить место на диске (и сейчас перенос файла с диска не возможен). Файл будет хорошо сжиматься с помощью gzip или bz2 или чего-то еще, но все эти программы записывают сжатый файл в отдельный файл. У меня недостаточно свободного места для этого.

Есть ли способ использовать стандартные инструменты сжатия или другие утилиты Unix для сжатия файла без использования дополнительного дискового пространства (или хотя бы минимального дополнительного дискового пространства)? Я представляю что-то, что сжимает часть файла за раз и записывает результаты прямо в файл. Я понимаю, что это было бы рискованно, поскольку файл был бы поврежден, если сжатие было прервано, но я не думаю, что у меня есть выбор.

4 ответа4

13

Это доказательство концепции bash one-liner, но оно должно помочь вам начать. Используйте на свой риск.

truncate -s `gzip -c file | dd of=file conv=notrunc 2>&1 | sed -n '$ s/ .*$// p'` file
mv file file.gz

Это работает путем передачи данных gz в процесс dd, который записывает их обратно в тот же файл. После завершения файл усекается до размера вывода gz.

Это предполагает, что последняя строка вывода dd соответствует:

Скопировано 4307 байт (4,3 кБ), 2,5855e-05 с, 167 МБ / с

Где первое поле является целым числом записанных байтов. Это размер файла, до которого нужно будет обрезаться. Я не уверен на 100%, что формат вывода всегда один и тот же.

6

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

Если у вас достаточно ОЗУ, вы можете написать скрипт для временного сжатия файлов в файловой системе tmpfs , затем удалить оригинал с диска и заменить его сжатой версией. Может быть, что-то вроде этого:

# some distributions mount /dev/shm as tmpfs; replace with bzip2 if you prefer
if gzip -q9c /full/disk/somefile > /dev/shm/somefile.gz
then
    rm -f /full/disk/somefile && mv -i /dev/shm/somefile.gz /full/disk
fi

Просто помните об использовании памяти, так как tmpfs - это, по сути, RAM-диск. Большой выходной файл может легко привести к истощению системы и вызвать другие проблемы для вас.

3

Нет инструмента, который бы работал таким образом, именно по той причине, которую вы указали. Мало кто готов написать инструмент, который сознательно реализует рискованное поведение.

1

Команды split и csplit можно использовать для разбиения большого файла на более мелкие части, а затем для их индивидуального сжатия. Сборка будет довольно трудоемкой, хотя.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .