Добавить / обновить файл в существующий архив tar.gz?

73

Есть ли способ добавить / обновить файл в архиве tar.gz? По сути, у меня есть архив, который содержит файл, /data/data/com.myapp.backup/./files/settings.txtи я хотел бы извлечь этот файл из архива (уже сделано) и вставить его обратно в архив после завершения редактирования. Как я могу сделать это? Это проблематично из-за .в пути?

Нафтули Кей
источник
2
+1. Это сделало бы работу над OS X такой простой. В настоящее время я должен вручную очистить каталог от всех скрытых файлов, таких как, .DS_Storeи затем повторно скопировать каталог.

Ответы:

15

Формат файла tar представляет собой просто серию файлов, соединенных вместе с несколькими заголовками. Это не очень сложная работа - разорвать ее на части, сложить содержимое и собрать обратно. При этом, Джандер описал, как tar как программа не имеет вспомогательных функций для этого, и есть дополнительные сложности со сжатием, которое должно иметь место как до, так и после внесения изменений.

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

Одним из первых вариантов будет проект архивирования для FUSE . Вот учебник по этому вопросу . В вашей системе, вероятно, уже есть FUSE, и если нет, то в вашем дистрибутиве должна быть опция.

Другой вариант - tarfs . Его проще использовать , но я слышал, что у него есть проблемы с повреждением архивов bzip2, поэтому вы можете сначала довольно тщательно его протестировать.

Калеб
источник
1
Я использую AVFS , которая упакована в Ubuntu и Debian. Знаете ли вы, как archivemount и tarfs сравниваются с AVFS?
Жиль "ТАК - перестань быть злым"
Честно говоря, нет, хотя мне любопытно взглянуть на AVFS сейчас, когда вы упомянули альтернативу. Я использовал и archivemount, и tarfs, но это был давно снятый с производства проект, и я не знаю их текущего состояния. Исходя из этого опыта, я вроде решил, что идея была концептуальной неверной, даже если реализация работала отлично.
Калеб
Я посмотрел, как работает архив Он не изменяет существующий файл .tar.gz, но при размонтировании переименовывает оригинал и создает на его месте новый файл tar. Если вы ищете хороший пользовательский опыт, это здорово, но если вы хотите избежать переписывания всего архива по соображениям эффективности, это вам не поможет.
Jander
@ Jander Это для указания на это. Я уверен, что это относится ко всем вариантам монтирования сжатого архива. Проблема заключается в том, что отдельные части файла не сжимаются, общие внутренние заголовки файла и все сжимаются, и для того, чтобы можно было извлечь что-то еще, ожидаемый gzip должен быть запущен по всему набору данных. Невозможно вставить что-то посередине, не извлекая и не перезапуская сжатие и не переписывая весь файл данных. Поэтому мой предыдущий комментарий о том, что это концептуально неправильное решение . Архивы есть архивы.
Калеб
43

Чтобы вытащить ваш файл из вашего архива, вы можете использовать tar xzf archive.tar.gz my/path/to/file.txt. Обратите внимание, что каталоги в пути к файлу также будут созданы. Используйте tar t(т.е. tar tzf archive.tar.gz), чтобы перечислить файлы в архиве.

tarне поддерживает обновление файлов на месте. Однако вы можете добавить файлы в конец архива, даже если они имеют тот же путь, что и файл, уже находящийся в архиве. В этом случае обе копии файла будут находиться в архиве, а файл, добавленный позже, переопределит предыдущую. Команда, которую нужно использовать для этого tar r(или tar uтолько для добавления файлов, которые новее, чем архив), это команда для использования. На .пути не должно быть проблем.

Однако есть одна загвоздка: вы не можете добавить в сжатый архив. Так что вы должны сделать:

gunzip archive.tar.gz
tar rf archive.tar data/data/com.myapp.backup/./files/settings.txt
gzip archive.tar

Что, вероятно, не то, что вы хотите услышать, поскольку это означает переписывание всего архива дважды. Если это не очень большой архив, возможно, лучше распаковать его целиком, а затем заново отредактировать после редактирования. Кроме того, вы можете использовать несжатый архив.

Jander
источник
Этот ответ верен только в том случае, если он касается стандартной tarпрограммы. Тар как формат файла на самом деле очень доступен. Вы можете легко написать скрипт для обновления содержимого самостоятельно, но есть другие инструменты, которые уже делают это .
Калеб
23
Вы также можете сделать это в стиле Unix:gzip -dc archive.tar.gz | tar -r data/data/com.myapp.backup/./files/settings.txt | gzip >archive_new.tar.gz
Саймон Рихтер
2
IIRC вы можете просто объединить два файла gzip. В результате получается файл большего размера, содержащий gzip, который содержит оба несжатых файла.
FUZxxl
Разархивирован ли файл, возможно ли использовать флаг --update?
пьетро
@FUZxxl +1 за упоминание конкатенации gzip
Йохан Буле
9

Изначально Tar предназначался для использования с лентами, поэтому «замена» файлов в действительности не предусмотрена. Однако вы можете использовать --delete для удаления файла из исходного tar, а затем -u для обновления tar и повторного добавления файла. Это может занять некоторое время, так как tar нуждается в внутренней реорганизации архива.

rleibman
источник
Добро пожаловать в StackExchange! Ваш ответ содержит только предложение, уже сделанное в другом ответе . Пожалуйста, прочитайте другие ответы на вопрос, прежде чем отвечать, чтобы избежать создания дубликатов.
JigglyNaga
1
Я немного отредактировал свой ответ. Я не думаю, что в другом ответе упоминается
delete
-5

на моем Linux x86_64 GNU / Linux для выполнения этой операции я просто использую следующую команду:

tar cvfpz /path/archive.tar -T list.txt

Эта команда вызывает создание сжатого архива /pathс использованием списка файлов, включенных в list.txtфайл.

user64312
источник
6
Это перезаписывает существующий файл /path/archive.tarвместо добавления / обновления этого файла.
Anthon