web-dev-qa-db-fra.com

Comment combiner la commande 'tar' avec 'find'

La commande find donne cette sortie:

 [root @ localhost /] # find var/log/-iname anaconda. * 
 var/log/anaconda.log 
 var/log/anaconda.xlog 
 var/log/anaconda.yum.log 
 var/log/anaconda.syslog 
 var/log/anaconda.program.log 
 var/log/anaconda.storage.log 

Après avoir combiné avec tar, il affiche cette sortie:

 [root @ localhost /] # find var/log/-iname anaconda. * -exec tar -cvf fichier.tar {} \; 
 var/log/anaconda.log 
 var/log/anaconda.xlog 
 var/log/anaconda.yum.log 
 var/log/anaconda.syslog 
 var/log/anaconda.program.log 
 var/log/anaconda.storage.log 

Mais tout en listant un fichier tar, il ne montre qu'un seul fichier

 [root @ localhost /] # tar -tvf file.tar 
 - rw ------- racine/racine 208454 2012-02-27 12:01 var/log/anaconda. stockage.log 

Qu'est-ce que je fais mal ici?

Avec xargs j'obtiens cette sortie:

[root @ localhost /] # find var/log/-iname anaconda. * | xargs tar -cvf fichier1.tar

Deuxième question

Pendant que vous tapez / devant var, signifie find /var/log, pourquoi donner ce message tar: Supprime le `/ 'précédent de noms de membres

 [root @ localhost /] # find/var/log/-iname anaconda. * -exec tar -cvf fichier.tar {} \; 
 tar: Suppression du `/ 'initial du nom des membres 
/var/log/anaconda.log 
 tar: suppression de l'interlignage `/ 'des noms de membre 
/var/log/anaconda.xlog 
 tar: suppression de l'interlignage `/ 'des noms de membres 
/var/log/anaconda.yum.log 
 tar: Suppression des` /' des noms de membres 
/var/log/anaconda.syslog 
 tar: Suppression des `/ 'du premier membre 
/var/log/anaconda.program.log 
 tar: Suppression du` /' du premier nom des membres 
/var/log/anaconda.storage.log 

Sous une forme simple, quelle est la différence entre les deux suivants?

find var/log et find /var/log

28
max

Notez que find appellera l'action -exec pour chaque fichier qu'il trouve.

Si vous exécutez tar -cvf file.tar {} pour chaque sortie de fichier find, cela signifie que vous écraserez file.tar à chaque fois, ce qui explique pourquoi vous vous retrouvez avec une archive qui ne contient que anaconda.storage.log - c'est le dernier fichier find.

Maintenant, vous voulez réellement ajouter les fichiers à l'archive au lieu de les créer à chaque fois (c'est ce que fait l'option -c). Alors, utilisez ce qui suit:

find var/log/ -iname "anaconda.*" -exec tar -rvf file.tar {} \;

L'option -r est ajoutée à l'archive au lieu de la recréer à chaque fois.

Remarque: Remplacez -iname anaconda.* par -iname "anaconda.*". L'astérisque est un caractère générique et peut être développé par votre Shell avant que find ne le voie même. Pour éviter cette expansion, placez l'argument entre guillemets.


En ce qui concerne tar, supprimant le / principal: l'archive ne doit contenir que des noms de fichiers relatifs. Si vous ajoutez des fichiers avec un / en tête, ils seront stockés sous forme de noms de fichiers absolus , ce qui signifie littéralement /var/… sur votre ordinateur, par exemple.

Ceci est simplement une précaution pour les implémentations tar autres que GNU, et est donc plus sûr car vous n'écraserez pas vos données réelles dans /var/… lorsque vous extrayez l'archive si elle contient des noms de fichiers relatifs.

37
slhck

Vous pouvez utiliser quelque chose comme:

find var/log -iname 'anaconda.*' -print0 | tar -cvf somefile.tar --null -T -

-print0 et -T fonctionnent ensemble pour autoriser les noms de fichiers avec des espaces, des nouvelles lignes, etc. Le - final indique à tar de lire les noms de fichiers d'entrée à partir de stdin.

Notez que -print0 doit figurer à la fin de votre déclaration, par cette réponse . Sinon, vous obtiendrez probablement plus de fichiers que prévu.

36
Iain

Essaye ça:

tar -cvf file.tar `find var/log/ -iname "anaconda.*"`

Vous essayiez d'utiliser find en -exec tar. Mais, de la manière dont fonctionne l’option -exec, il exécute cette commande une fois pour chaque fichier correspondant trouvé, ce qui entraîne le remplacement par tar du fichier tar généré à chaque fois. C'est pourquoi vous ne vous êtes retrouvé qu'avec le dernier. De plus, vous devez mettre des guillemets autour du modèle que vous spécifiez à find afin que le shell ne le développe pas avant de le transmettre à find.

En utilisant la substitution de commande avec des backticks (ou en utilisant la notation $(...) si vous préférez), la liste complète des noms produits par find est collée sur la ligne de commande sous forme d'arguments à tar, ce qui a pour effet qu'elle les écrit tous en même temps.

11
Nicole Hamilton

Question 1

Votre commande échoue car tar récupère chacun des fichiers trouvés et les archive dans file.tar. Chaque fois qu'il le fera, il écrasera le file.tar créé précédemment.

Si ce que vous voulez, c'est une archive avec tous les fichiers, lancez simplement tar directement, il n'y a pas besoin de find (et oui, cela fonctionne pour les fichiers avec des espaces dans leurs noms):

tar -vcf file.tar /var/log/anaconda*   

Question 2

Les deux commandes sont complètement différentes:

  • find var/log recherchera un répertoire appelé var/log, qui est un sous-répertoire de votre répertoire actuel , il équivaut à find ./var/log (remarquez le ./).

  • find/var/log recherchera un répertoire appelé /var/log, qui est un sous-répertoire de la racine, /.

Le premier message / provient de tar et non pas find. Cela signifie qu’il supprime le premier / de vos noms de fichier pour créer des chemins absolus en relatifs . Cela signifie que le fichier de /var/log/anaconda.error sera extrait à ./var/log/anaconda.error lorsque vous décompactez l'archive.

6
terdon

Je pense que l’utilisation de -exec pour chaque fichier peut ralentir la compression du fichier tar si vous avez beaucoup de fichiers. Je préfère utiliser la commande:

find . -iname "*.jpg" | cpio -ov -H tar -F jpgs.tar
1
fabceolin

-exec peut fonctionner de deux manières. Une manière exécute la commande plusieurs fois - une fois pour chaque fichier; dans l'autre cas, la commande est exécutée une fois, y compris tous les fichiers sous forme de liste de paramètres.

  • -exec tar -cvf file.tar {} ';' exécute la commande tar pour chaque fichier, écrasant l'archive à chaque fois.
  • -exec tar -cvf file.tar {} '+' exécute la commande tar une fois, créant une archive de tous les fichiers trouvés.
1
mwfearnley