Префикс префикса в tar

17

В настоящее время я делаю в сценарии очень неэффективно:

cp -a $MYPATH /tmp/$VERSION
cd /tmp
tar cjf archive.tar.bz2 $VERSION

Я хочу, чтобы все содержалось в каталоге с именем $ VERSION - есть ли способ сделать это без необходимости копировать все, как в приведенном выше сценарии?

Robby75
источник
Зачем копировать это в первую очередь? Почему нет tar cjf archive.tar.bz2 $MYPATH?
Chewie
2
@ Чеви, он сказал, он хочет $ версию как родительский каталог в архиве.
Кент
О, я вижу это сейчас.
Chewie

Ответы:

26

Версия GNU tarподдерживает --transformопцию (и ее псевдоним --xform), вы можете использовать ее следующим образом

tar --transform "s/^$MYPATH/$VERSION/" -cf archive.tar.bz2 "$MYPATH"

Например, учитывая это дерево каталогов

foo
└── foo.txt

команда

tar --transform "s/^foo/bar/" -cf foo.tar.bz2 foo

создаст архив как

$ tar -tf foo.tar.bz2
bar/
bar/foo.txt
toro2k
источник
3
Примечательно, что такой подход может разорвать символические ссылки. Предварительное flags=r;решение решает проблему, как указано в stackoverflow.com/a/29661783/388803 .
eregon
не включайте косую черту; когда я добавляю косую черту в преобразование, исходный префикс пропускается; например s/^a\//b\//, tar -tвсе еще показывает, в a/то время как все другие файлы находятся под b/; Я предполагаю, что это опасно, и мне не нужно защищать от какого-либо другого файла с тем же префиксом, который не является каталогом в файле tar; так что никакой косой черты в порядке, я не возражаю, зная, как лучше всего справиться со случаем a/трансформации, но не в том aa/случае, если это был брат или сестра корневого узла.
ThorSummoner
15

Чтобы сменить текущий каталог и добавить префикс, это сработало для меня:

tar --transform 's,^\.,$VERSION,' -cf foo.tar .
Энди Валаам
источник
0

Если вы можете уйти без сохранения символических ссылок в файловом дереве, которое вы используете, вы можете сделать

ln -s $MYPATH /tmp/$VERSION
cd /tmp
tar cjhf archive.tar.bz2 $VERSION

В hсредства опции разыменования символические ссылки, то есть включать в файл или каталог, ссылка указывает , а не просто записывает тот факт , что там была символическая и то , что он указал.

Ян Робертс
источник
0

Для удобного добавления префикса каталога используйте другой разделитель, чем /в --transformаргументе, например +или ,как в ответе Энди.

Итак, для более простого случая у вас есть куча файлов в текущем каталоге, и вы не хотите создавать tarbomb .

tar czf logs_nightly.tar.gz --tranform 's+^+logs_nightly/+' *.log

Синтаксис s+search+replace+, и для ^него просто совпадает с началом имени файла.

А теперь, просто чтобы ответить на OP - вы можете избежать копирования всего каталога /tmp, выполнив:

mv $MYPATH $VERSION
tar cjf archive.tar.bz2 $VERSION
mv $VERSION $MYPATH

В качестве альтернативы:

ln $MYPATH $VERSION
tar cjf archive.tar.bz2 $VERSION

(жесткая ссылка, избегает проблем с символическими ссылками)

Последние два были включены для развлекательной ценности, я сам придерживался ответа toro2k.

Томаш Гандор
источник