Оскільки файли tar є потоковим форматом - ви можете їх catдва разом і отримати майже правильний результат - для цього вам не потрібно витягувати їх на диск. Ви можете розпаковувати (лише) файли, об'єднувати їх разом і повторно стискати цей потік:
xzcat *.tar.xz | xz -c > combined.tar.xz
combined.tar.xzбуде стислим тарболом усіх файлів у складі tarballs, які лише незначно пошкоджені. Для вилучення вам доведеться скористатися --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
Це дещо менш ефективно з точки зору остаточного стисненого розміру, оскільки в потоці є додаткові заголовки дьогтю, але економиться час на витяг та повторне додавання всіх файлів у вигляді файлів. У вас є combined.tar.xzбагато (нестиснених) db-*.tarфайлів.