Добавление файла в файлы tbz

8

Я ищу способ обновить тысячи архивных файлов .tbz, поэтому я буду делать это с помощью сценария оболочки. Мне нужно добавить один файл к каждому.

Мой вопрос: есть ли более быстрый способ сделать это, не извлекая содержимое каждого tbz, а затем повторно сжимая его с новым файлом, включенным в содержащийся tar? Как будут выглядеть команды?

Спасибо

BottleZero
источник
Очевидная альтернатива - поместить сжатые файлы в несжатый архив. Но это меняет формат данных, поэтому он может оказаться неэффективным для вас и может оказаться неэффективным для большого количества небольших файлов с избыточностью между ними.
Восстановите Монику

Ответы:

12

Хотя tarможно добавлять файлы в уже существующий архив, его нельзя сжать. Вам придётся bunzip2сжать архив, оставив стандартный тарбол. Затем вы можете использовать tarвозможность добавлять файлы в существующий архив, а затем повторно сжимать bzip2.

Из руководства:

 -r      Like -c, but new entries are appended to the archive.  Note that this only
         works on uncompressed archives stored in regular files.  The -f option is
         required.
DopeGhoti
источник
это действительно правда
Kiwy
Это один метод, но это не единственный метод. Можно изменить поток bzip2, не распаковывая его полностью. Я не знаю, возможно ли это сделать так, чтобы можно было аккуратно добавить в архив tar, но dhag показывает частичный метод.
Жиль "ТАК - перестань быть злым"
10

Другой ответ правильный: вы не можете правильно обновить сжатый tar-архив, не распаковывая его. В документации GNU tar на это намекает, и попытка обновления завершается неудачно с явным сообщением об ошибке:

$ tar --concatenate --file=cat.tar.bz2 two.tar.bz2 
tar: Cannot update compressed archives
tar: Error is not recoverable: exiting now

Однако, если вас заинтересует грязное решение, не требующее распаковки, я могу предложить его на основе следующих наблюдений:

  • catПоддерживается добавление потоков bzip2 с использованием и создает действительный поток bzip2 (то же самое относится и к gzip);
  • добавление команды cattar не дает действительный файл tar, поэтому --concatenateопция существует, но мы можем попросить tar сделать вид, что она действительна:

Вам может показаться более интуитивным желание или попытка использовать cat для объединения двух архивов вместо использования --concatenateоперации; В конце концов, cat - это утилита для объединения файлов.

Тем не менее, архивы tar содержат маркер конца файла, который необходимо удалить, если объединенные архивы должны быть правильно прочитаны как один архив. --concatenateудаляет маркер конца архива из целевого архива перед добавлением каждого нового архива. Если вы используете cat для объединения архивов, результатом будет неправильный архив формата tar. Если вам нужно извлечь файлы из архива, который был добавлен в утилиту cat, используйте опцию --ignore-zeros( -i).

На основании этих знаний мы можем сделать, например:

cat {one,two}.tar.bz2 >combined.tar.bz2

Это приводит, как объясняет приведенный выше фрагмент документации, к неверному файлу tar, но при использовании --ignore-zerosего все равно можно прочитать полностью:

## Show contents of `one.tar.bz2'
$ tar tf one.tar.bz2
a
b

## Show contents of `two.tar.bz2'
$ tar tf two.tar.bz2
c

## Show contents of `combined.tar.bz2', bypassing the bad format
$ tar tif combined.tar.bz2
a
b
c

Обратите внимание, что в приведенном выше списке перечислены все три файла из двух исходных архивов, тогда как при пропуске -i(правильно) перечислены только файлы из первого исходного архива:

$ tar tf combined.tar.bz2 
a
b

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

dhag
источник
Это очень интересно, спасибо за подробный ответ. К сожалению, я не контролирую процесс, который в конечном итоге прочитает эти архивы.
BottleZero
Это можно использовать, чтобы «спрятать» некоторые файлы в архиве, так что кто-то, случайно извлекающий, получит только содержимое оригинального архива, но те, кто знает, как добавить iего в командную строку, увидят все это.
Монти Хардер