Copiez chaque fichier d'une structure de répertoires dans un chemin spécifique uniquement si le fichier n'existe pas déjà

8

Voudrait copier chaque fichier d'une structure de répertoires vers un répertoire spécifique uniquement si le fichier n'existe pas déjà.

Vous avez la première partie de cette question de débordement de pile :

find . -type f -exec cp {} /target-directory \;

Comment puis-je vérifier si le fichier existe ou non? Sinon, copiez le fichier, sinon sautez.

monsieur au
la source
Voulez-vous dire "copier tous les fichiers de l'arborescence source dans un répertoire unique (spécifique) sans sous-répertoires"? Ou "copier tous les fichiers de l'arborescence source dans un sous-répertoire du répertoire de destination similaire à celui où il se trouvait dans l'arborescence source"? J'ai lu la question comme le premier cas - pouvez-vous modifier la question pour clarifier? (Je sais que vous avez votre réponse, mais elle sera lue et utilisée par d'autres.)
Volker Siegel

Réponses:

13

Vous pouvez utiliser la -ucommande switch from cp:

copier uniquement lorsque le fichier SOURCE est plus récent que le fichier de destination ou lorsque le fichier de destination est manquant

ou utilisez la rsynccommande avec --ignore-existing:

ignorer la mise à jour des fichiers qui existent sur le récepteur

Exemple:

rsync --ignore-existing source/* destination/
Ravexina
la source
3

Votre commande d'origine peut être réécrite comme:

find . -type f -exec bash -c 'test -e /target-directory/"$1" || cp "$1" /target-directory' sh {} \;

La clé ici est que nous appelons shell avec des commandes spécifiques et passons le fichier trouvé en $1argument. En cas d' test -e /target-directory/"$1"échec, cela signifie que le fichier n'existe pas, auquel cas cpil copiera le fichier.

En général, on peut utiliser d'autres commandes, tant que la commande peut vérifier l'existence d'un fichier. Certaines des autres alternatives:

  • /usr/bin/realpath -e /target-directory/"$1" > /dev/null || cp "$1" /target-directory
  • stat >/dev/null /target-directory/"$1" || cp "$1" /target-directory/"$1"
Sergiy Kolodyazhnyy
la source
2
Pourquoi stattester l'existence d'un fichier dans Bash? Ce ne serait pas test -ebeaucoup plus simple?
David Foerster
@DavidFoerster Aucune raison particulière. La commande test fera aussi l'affaire. Je modifierai ma réponse plus tard si je n'oublie pas
Sergiy Kolodyazhnyy
0

Lisez man cpet utilisez l' --no-clobberoption pour cp.

waltinator
la source