116 votes

Trouver des fichiers et les goudronner (avec des espaces)

D'accord, alors un problème simple ici. Je travaille sur un simple code de secours. Ca marche bien sauf si les fichiers contiennent des espaces. Voici comment je trouve les fichiers et les ajoute à une archive tar :

find . -type f | xargs tar -czvf backup.tar.gz 

Le problème est que lorsque le fichier comporte un espace dans son nom, tar pense qu'il s'agit d'un dossier. En fait, existe-t-il un moyen d'ajouter des guillemets autour des résultats de find ? Ou un autre moyen de résoudre ce problème ?

12 votes

La meilleure façon d'utiliser find ... | xargs ... est d'utiliser le paramètre -print0/-0 sur chacun : find -print0 ... | xargs -0 ... . Les noms de fichiers seront alors séparés par un caractère nul, ce qui signifie que vous pouvez avoir des espaces, des retours à la ligne ou d'autres éléments bizarres dans vos noms de fichiers et que cela fonctionnera quand même.

8 votes

Il y a un problème à utiliser xargs et tar de cette façon lorsque vous avez un grand nombre de fichiers, xargs invoquera tar -c de manière répétée, et cela continuera à écraser votre archive, et le résultat est que vous n'aurez pas tous les fichiers que vous attendez. Voir cette explication plus détaillée y ma réponse ci-dessous.

228voto

Steve Kehlet Points 1294

Utilisez ça :

find . -type f -print0 | tar -czvf backup.tar.gz --null -T -

Il le fera :

  • gérer les fichiers contenant des espaces, des nouvelles lignes, des tirets de tête et autres bizarreries
  • traiter un nombre illimité de fichiers
  • n'écrasera pas de manière répétée votre backup.tar.gz comme en utilisant tar -c con xargs fera lorsque vous aurez un grand nombre de fichiers

Voir aussi :

1 votes

Comment faire si vous voulez faire passer votre recherche par sed plusieurs fois d'abord ? par exemple find . -print0 | sed /backups/d | tar....

10 votes

Notez que si vous avez plusieurs conditions, vous devez ajouter des parenthèses. Sinon, le -print0 s'applique uniquement à la dernière expression. Par exemple find . \( -type f -o -name '*.c' \) -print0 | ...

1 votes

Pour le plaisir, voici une version Windows de ceci en utilisant cygwin : c:\cygwin\bin\find . -regextype posix-egrep -regex '.*(sln^|vcxproj^|filters)$' -print0 | c:\cygwin\bin\tar -cvf MS_Projects.tar --null -T -

17voto

errorprone Points 74

Il pourrait y avoir un autre moyen d'obtenir ce que vous voulez. En gros,

  1. Utilisez le trouver pour afficher le chemin vers les fichiers que vous recherchez. Rediriger stdout vers un nom de fichier de votre choix.
  2. Puis tar avec l'option -T qui lui permet de prendre une liste d'emplacements de fichiers (celle que vous venez de créer avec find !).

    find . -name "*.whatever" > yourListOfFiles
    tar -cvf yourfile.tar -T yourListOfFiles

0 votes

Il y a une réponse ici sur la façon de gérer les noms de fichiers contenant des sauts de ligne : superuser.com/a/513319/151261

8voto

gsteff Points 1674

Essayez de courir :

    find . -type f | xargs -d "\n" tar -czvf backup.tar.gz

7voto

Warren P Points 23750

Pourquoi pas :

tar czvf backup.tar.gz *

Bien sûr, c'est intelligent d'utiliser find et ensuite xargs, mais vous le faites de la manière la plus difficile.

Mise à jour : Porges a commenté avec une option de recherche qui, à mon avis, est une meilleure réponse que la mienne ou que l'autre : find -print0 ... | xargs -0 ....

0 votes

Mon code complet ne sauvegardera que les éléments qui ont été modifiés au cours de la dernière journée. Comme il s'agit d'une sauvegarde quotidienne, je ne veux pas avoir d'informations répétées pour économiser sur la taille du fichier (je fais également une sauvegarde complète tous les 15 jours).

0 votes

Pour que cette question soit mieux adaptée à l'OS, je poserais la question suivante : " utiliser de manière fiable find, xargs et tar ensemble ". Votre titre et votre question ne précisent pas vraiment que vous avez besoin de find et xargs, et pourtant vous en avez besoin.

0 votes

xargs ... tar c ... écrasera la première archive créée si la liste des fichiers est trop longue et que xargs exécutera tar pour la deuxième fois ! Pour éviter l'écrasement, vous pouvez utiliser xargs -x mais alors l'archive pourrait être incomplète. Une alternative pourrait être de commencer par tar c ... puis éventuellement à plusieurs reprises tar r ... . (ma contribution à la fiabilité :)

0voto

Elvis Ciotti Points 1384

Une alternative, sans utiliser xargs, est d'utiliser la commande -exec au paramètre find . Cela a toujours bien fonctionné pour moi.

find . -type f -exec tar -czvf backup.tar.gz {} \;

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X