Оскільки файли 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
файлів.