Вопрос или проблема
Предположим, у меня есть большой sample.tar
с содержимым:
foo/...
bar/...
baz/...
...
Как разделить на два несовместимых архива так, чтобы один архив содержал файлы, соответствующие шаблону, а другой архив – остальное?
Попытка
Посмотрев на --delete
в GNU tar, идея заключалась в том, чтобы сделать 2 копии и удалить соответствующие части. Эта сторона работает прекрасно:
tar -vf sample.tar --delete --wildcards 'foo/*' 'bar/*'
Как отрицать выбор? Похоже, что --delete
не работает хорошо с --exclude
, так как ни один из следующих вариантов не срабатывает (удаляет всё):
tar -vf sample.tar --delete --wildcards '*' --exclude="foo/*" --exclude="bar/*"
tar -vf sample.tar --delete --wildcards --exclude="foo/*" --exclude="bar/*" '*'
Заметки
- Я не хочу пересобирать архив, чтобы сохранить все атрибуты (идентификаторы пользователей, бит setuid, временные метки и т.д.)
- Я не хочу использовать дополнительные инструменты, которые не входят в стандартную дистрибуцию (apt install из стандартного репозитория – нормально, компиляция из исходников – нет)
- Я могу представить подход бедного человека, перечисляя содержимое с помощью
tar -t ...
и генерируя аргументы для отрицанного выбора, но надеюсь, что есть лучший способ - Вышеупомянутые эксперименты проводились с GNU tar 1.34
Ответ или решение
Чтобы эффективно разделить tar-архив на два, сохраняя все атрибуты файлов, можно использовать возможности утилиты GNU tar, не прибегая к дополнительным инструментам. Ваша задача заключается в создании двух независимых tarball: один для файлов, соответствующих определённому шаблону, а другой для оставшихся файлов. Рассмотрим все шаги подробно.
Шаг 1: Разделение архива
Вы можете использовать существующий tar-архив, чтобы создать два новых. Вместо использования флага --delete
, который может вызвать проблемы в таком контексте, разумнее будет извлечь всё содержимое в временную папку, а затем создать два новых архива.
Извлечение содержимого в временную папку
Создадим временную папку и извлечем в неё содержимое архива:
mkdir /tmp/sample_tar_extract
tar -xf sample.tar -C /tmp/sample_tar_extract
Создание архива с файлами, соответствующими шаблону
Теперь создайте первый tar-архив, содержащий только нужные файлы. В вашем случае предполагаем, что вы хотите включить файлы, соответствующие шаблону ‘foo/‘ и ‘bar/‘:
tar -cf sample_matching.tar -C /tmp/sample_tar_extract 'foo/*' 'bar/*'
Создание архива с оставшимися файлами
Теперь создайте второй архив, который будет содержать все остальные файлы. Для этого вы можете использовать --exclude
в процессе создания архива, чтобы исключить файлы, которые уже были добавлены в первый архив:
tar -cf sample_non_matching.tar -C /tmp/sample_tar_extract --exclude='foo/*' --exclude='bar/*' .
Шаг 2: Удаление временной папки
После того, как оба архива были созданы, вы можете удалить временную папку:
rm -rf /tmp/sample_tar_extract
Заключение
Таким образом, вы успешно разделили большой tar-архив на два меньших, сохраняя все атрибуты файлов и избегая использования ненадежных методов, таких как --delete
. Такой способ также предохраняет ваши данные от опасности потери информации или изменения атрибутов при повторной упаковке.
Этот процесс является стандартным в большинстве дистрибутивов и не требует установки дополнительных утилит, что соответствует вашим требованиям.