Поскольку 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файлов.