Как разбить архив tar на файлы, соответствующие шаблону?

Вопрос или проблема

Предположим, у меня есть большой 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. Такой способ также предохраняет ваши данные от опасности потери информации или изменения атрибутов при повторной упаковке.

Этот процесс является стандартным в большинстве дистрибутивов и не требует установки дополнительных утилит, что соответствует вашим требованиям.

Оцените материал
Добавить комментарий

Капча загружается...