Поскольку tar-файлы являются потоковым форматом - вы можете cat
объединить их два и получить почти правильный результат - вам вообще не нужно извлекать их на диск для этого. Вы можете распаковать (только) файлы, объединить их вместе и повторно сжать этот поток:
xzcat *.tar.xz | xz -c > combined.tar.xz
combined.tar.xz
будет сжатый архив всех файлов в компонентных архивах, который только слегка поврежден. Для извлечения вам придется использовать эту --ignore-zeros
опцию (в GNU tar
), потому что у архивов есть маркер «конца файла», который появится в середине результата. Кроме этого, все будет работать правильно.
GNU tar
также поддерживает --concatenate
режим для создания комбинированных архивов. Это имеет те же ограничения, что и выше - вы должны использовать --ignore-zeros
для извлечения - но это не работает со сжатыми архивами. Вы можете создать что-то, чтобы обмануть это, используя подстановку процессов, но это хлопотно и даже более хрупко.
Если есть файлы, которые появляются в разных tar-файлах более одного раза, это не будет работать должным образом, но у вас есть проблема, независимо от того. В противном случае это даст вам то , что вы хотите - конвейерный вывод через xz
то , как в tar
любом случае сжимает свою продукцию.
Если архивы, которые работают только с определенной tar
реализацией, не подходят для ваших целей, то добавление в архив с r
вашим другом:
tar cJf combined.tar.xz dummy-file
for x in db-*.tar.xz
do
mkdir tmp
pushd tmp
tar xJf "../$x"
tar rJf ../combined.tar.xz .
popd
rm -r tmp
done
При этом извлекается только один архив за раз, поэтому рабочее пространство ограничено размером содержимого одного архива. Сжатие передается точно так же, как если бы вы сделали окончательный архив одновременно, так что оно будет таким же хорошим, как могло бы быть. Вы выполняете много лишних операций распаковки и повторного сжатия, которые будут делать это медленнее, чем cat
версии, но полученный архив будет работать где угодно без какой-либо специальной поддержки.
Обратите внимание, что - в зависимости от того, что именно вы хотите - достаточно добавить сами несжатые tar-файлы в архив. Они будут сжимать (почти) точно так же, как и их содержимое в одном файле, и это уменьшит накладные расходы на сжатие для каждого файла. Это будет выглядеть примерно так:
tar cJf combined.tar.xz dummy-file
for x in db-*.tar.xz
do
xz -dk "$x"
tar rJf combined.tar.xz "${x%.xz}"
rm -f "${x%.xz}"
done
Это немного менее эффективно с точки зрения окончательного сжатого размера, поскольку в потоке есть дополнительные заголовки tar, но экономит некоторое время на извлечение и повторное добавление всех файлов в виде файлов. В итоге вы получите combined.tar.xz
много (несжатых) db-*.tar
файлов.