création d'archive à l'aide de tar incluant tous les 'dotfiles' mais excluant tous les sous-répertoires et la structure de répertoires / wo

18

Je veux sauvegarder tous les 'dotfiles' (fe .zshrc) sous mon répertoire personnel avec tar , mais en excluant la structure du répertoire et tous les sous-répertoires.

Je l'ai essayé plusieurs fois avec différentes commandes, mais le meilleur que j'ai réalisé était une archive qui comprenait également les répertoires cachés $HOME.

#!/bin/zsh
BACKUPFILE=dotfile_backup.tar.gz
tar --create --file=$HOME/$BACKUPFILE --auto-compress --no-recursion --exclude=. --exclude=.. --exclude=*/ --directory=$HOME .*

J'ai aussi pensé à utiliser findet à canaliser le résultat sur tar, mais sans succès. Est-ce que quelqu'un sait comment accomplir cette tâche - apparemment facile -?

PS: La plupart du temps, lorsque j'utilise tar pour créer une archive, je dois penser à la bande dessinée xkcd:

xkcd 1168 :)

klingt.net
la source
La réponse de sim fonctionne, mais si quelqu'un a une expression régulière qui ne correspond qu'aux fichiers cachés, veuillez la poster!
klingt.net
1
Cela serait sûrement mieux réalisé avec votre coque. Je comprends que zsh a globs qui sélectionnent uniquement les fichiers - *(.)- et je pense qu'il exclut .et ..de .*par défaut (et ils ne seraient pas repris par de .*(.)toute façon, puisqu'il sélectionne uniquement les fichiers). Je n'utilise pas moi-même zsh, donc je ne suis pas assez sûr pour en faire une réponse.
evilsoup

Réponses:

14

Vous pouvez utiliser cette commande pour sauvegarder tous vos fichiers dot (.<something> ) dans votre $HOMErépertoire:

$ cd ~
$ find . -maxdepth 1 -type f -name ".*" -exec tar zcvf dotfiles.tar.gz {} +

regex en utilisant juste du goudron?

méthode # 1

J'ai fait des recherches sur ce sujet un peu et suis venu vide. Le facteur limitant serait que lorsquetar exécution, il est exclu, la barre oblique de fin ( /) qui s'affiche avec les répertoires ne fait pas partie de l'équation lorsque tar effectue sa correspondance de modèle.

Voici un exemple:

$ tar -v --create --file=do.tar.gz --auto-compress --no-recursion --exclude={'.','..','.*/'} .*
.qalculate/
.qt/
.qterm/
.qtoctave/
.RapidSVN
.RData
.Rhistory

Cette variante comprend une exclusion de .*/ et vous pouvez voir avec le commutateur prolixe activé sur tar -v, que ces répertoires passent par cette exclusion.

méthode # 2

Je pensais que les interrupteurs --no-wildcards-match-slashou--wildcards-match-slash relâcheraient la gourmandise du .*/mais cela n'a eu aucun effet non plus.

La suppression de la barre oblique de l'exclusion .*n'était pas non plus une option car cela indiquerait tard'exclure tous les fichiers et répertoires de points:

$ tar -v --create --file=do.tar.gz --auto-compress --no-recursion --exclude={'.','..','.*'} .*
$

méthode # 3 (moche!)

Donc, la seule autre alternative que je peux concevoir est de fournir une liste de fichiers tar. Quelque chose comme ça:

$ tar -v --create --file=do.tar.gz --auto-compress --no-recursion --wildcards-match-slash --exclude={'.','..','.*/'} $(ls -aF | grep -E "^\..*[^/]$")
.RapidSVN
.RData
.Rhistory

Cette approche pose des problèmes si le nombre de fichiers dépasse la quantité maximale d'espace pour passer des arguments à une commande serait un problème flagrant. L'autre, c'est que c'est moche et trop complexe.

alors qu'avons-nous appris?

Il ne semble pas y avoir de méthode simple et élégante pour réaliser cette utilisation tardes expressions régulières. Pour ce qui est du commentaire de @ terdon, find ... | tar ...c'est vraiment la façon la plus appropriée de le faire.

slm
la source
Je voulais vraiment y arriver regex, mais j'aurais dû savoir que cela ne fonctionnerait pas de cette façon :)
klingt.net
@ klingt.net - ça devrait être possible, je regarde maintenant.
slm
@ klingt.net pourquoi préféreriez-vous la manière la plus compliquée? L' utilisation que regexvous aurez probablement besoin d'échapper au premier point et auront du mal à ignorer .et ... Je suis sûr que c'est possible, comme le démontrera probablement slm, mais je ne vois pas pourquoi cela en vaudrait la peine.
terdon
1
@ klingt.net - tout ce que la findcommande trouve est passé en argument tar. Le {}dit où vous voulez que ces résultats aillent dans la -execcommande correspondante . Le +dit d'ajouter autant de résultats findque possible sur la ligne de commande et d'appeler tarseulement quelques fois plutôt que chaque fois qu'un résultat est trouvé.
slm
1
@ klingt.net - il n'y a aucun moyen d'y parvenir en utilisant regexet tarparce qu'il n'y a aucun moyen d'isoler les répertoires de points ( .blah/). Tar n'utilise pas la barre oblique de fin lors de l'exclusion.
slm
4

Ce type de contrôle sur les fichiers correspondants est bien en dehors de la zone de confort de tar. Ses règles de correspondance des fichiers sont limitées à de simples correspondances sur des noms.

find est une façon, mais puisque vous avez zsh, vous avez plus facile:

tar -cf "$HOME/$BACKUPFILE" --auto-compress .*(.)

Cela .entre parenthèses à la fin de l'expression générique est un qualificatif glob qui dit "ne correspond qu'aux fichiers normaux".

Les liens symboliques vers des fichiers normaux ne correspondent pas. Si vous passez à .*(-.), ils seront inclus, mais le fichier ne se retrouvera pas dans l'archive à moins qu'il ne soit également inclus. Si vous souhaitez remplacer le lien symbolique par leurs cibles, faites cela .*(-.:A):Aajoute le modificateur d'expansion de l' historique qui résout tous les liens symboliques à un chemin qui n'utilise pas de liens symboliques.

Gilles 'SO- arrête d'être méchant'
la source
3

Cette réponse est basée sur slm, mais je vais également vous montrer comment inclure des répertoires commençant par .

Pour compresser les fichiers dot dans votre répertoire personnel:

$ cd
$ find . -maxdepth 1 -type f -name ".?*" -exec tar czfv dotfiles.tgz {} +

Pour inclure des répertoires:

$ find . -maxdepth 1 -name ".?*" -exec tar czfv dotfiles.tgz {} +

Le ?est facultatif dans la première commande, mais pas dans la seconde, sinon, findinclura le .répertoire (actuel).

sudoman
la source
1

qu'en est-il de:

tar -C $HOME -cvzf dotfiles.tgz .
anonyme
la source