Ajouter un préfixe dans tar

17

Je fais actuellement dans un shellscript très inefficacement:

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

Je veux que tout soit contenu dans le répertoire appelé $ VERSION - existe-t-il un moyen de le faire sans avoir à tout copier comme dans le script ci-dessus?

Robby75
la source
Pourquoi le copier en premier lieu? Pourquoi pas tar cjf archive.tar.bz2 $MYPATH?
Chewie
2
@Chewie a-t-il dit, il veut la version $ comme répertoire parent dans l'archive.
Kent
Oh, je le vois maintenant.
Chewie

Réponses:

26

La version GNU de tarprend en charge l' --transformoption (et son alias --xform), vous pouvez l'utiliser comme ceci

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

Par exemple, étant donné cette arborescence de répertoires

foo
└── foo.txt

la commande

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

produira une archive comme

$ tar -tf foo.tar.bz2
bar/
bar/foo.txt
toro2k
la source
3
Il est à noter que cette approche pourrait rompre les liens symboliques. La pré- flags=r;résolution résout le problème tel que mentionné dans stackoverflow.com/a/29661783/388803 .
eregon
n'incluez pas de barre oblique de fin; lorsque je mets une barre oblique de fin dans la transformation, le préfixe d'origine est manquant; par exemple s/^a\//b\//, la tar -tmontre toujours a/alors que tous les autres fichiers sont sous b/; Je suppose que c'est dangereux, et je n'ai pas vraiment besoin de me protéger contre un autre fichier avec le même préfixe qui n'est pas un répertoire dans le fichier tar; donc aucune barre oblique ne va bien, cela ne me dérangerait pas de savoir la meilleure façon de gérer le cas de la a/transformation, mais pas aa/s'il s'agissait d'un frère du nœud racine.
ThorSummoner
15

Pour tarer le répertoire courant et ajouter un préfixe, cela a fonctionné pour moi:

tar --transform 's,^\.,$VERSION,' -cf foo.tar .
Andy Balaam
la source
0

Si vous pouvez vous en sortir sans conserver de liens symboliques dans l'arborescence de fichiers que vous goudronnez, vous pouvez le faire

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

L' hoption signifie des liens symboliques de déréférencement, c'est-à-dire inclure le fichier ou le répertoire vers lequel le lien pointe plutôt que d'enregistrer simplement le fait qu'il y avait un lien symbolique et ce qu'il pointait.

Ian Roberts
la source
0

Pour ajouter un préfixe de répertoire confortablement, utilisez un séparateur différent de celui /de l' --transformargument, par exemple +ou ,similaire dans la réponse d'Andy.

Donc, pour un cas plus simple, vous avez un tas de fichiers dans le répertoire actuel et vous ne voulez pas créer de tarbomb .

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

La syntaxe est s+search+replace+, et correspond ^simplement au début du nom de fichier.

Et maintenant, juste pour répondre à l'OP - eh bien, vous pouvez éviter de copier tout votre répertoire /tmpen exécutant:

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

Alternativement:

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

(lien dur, évite les problèmes avec les liens symboliques)

Les deux derniers ont été inclus pour la valeur de divertissement, je m'en tiendrai à la réponse de toro2k.

Tomasz Gandor
la source