Copier des fichiers sans écraser

99

Je n'arrive tout simplement pas à trouver un moyen sur la ligne de commande de dire "copiez tous les fichiers du répertoire A vers le répertoire B, mais si le fichier existe déjà dans le répertoire B, ne l'écrasez pas, quel que soit le fichier le plus récent , et ne me demandez pas. "

J'ai traversé la copie, le déplacement, la xcopy et la robocopy, et le plus proche que je puisse obtenir est que vous pouvez dire à robocopy "copier A vers B, mais n'écrasez pas les fichiers plus récents avec des fichiers plus anciens", mais cela ne fonctionne pas pour moi . J'ai regardé xxcopy, mais je l'ai jeté, car je ne veux pas avoir une dépendance tierce sur un événement post-build de Visual Studio qui nécessitera que d'autres utilisateurs SVN aient cet outil installé afin de faire la génération.

Je souhaite ajouter une ligne de commande à l'événement de post-génération dans Visual Studio 2010 afin que les fichiers générés à partir des modèles T4 pour les nouveaux objets de modèle EF soient distribués dans les dossiers de projet auxquels ils appartiennent, mais les fichiers régénérés pour les objets existants n'écrasez pas les fichiers de destination potentiellement modifiés.

Puisque le modèle T4 se régénère, le fichier source est toujours plus récent, et je ne peux pas utiliser le commutateur «plus récent» de manière fiable, je ne pense pas.

J'utilise des classes partielles pour les éléments pour lesquels je peux, mais il y a d'autres choses que je génère qui ne peuvent pas utiliser de classes partielles (par exemple, générer un fichier EditorTemplate ou DisplayTemplate * .ascx par défaut).

Quelqu'un a-t-il des problèmes similaires qu'ils ont résolus?

Tony
la source
Connaissez-vous cmd.exela forcommande de? Sinon, je vous recommande de courir for /?et de l'utiliser.
Gabe

Réponses:

38
For %F In ("C:\From\*.*") Do If Not Exist "C:\To\%~nxF" Copy "%F" "C:\To\%~nxF"
Stu
la source
5
Cela a fonctionné pour moi, mais j'ai dû utiliser deux symboles pour cent au lieu d'un seul car je l'exécutais à partir d'un fichier de commandes plutôt que de la ligne de commande. J'ai remplacé les instances de% F par %% F et les instances de% ~ nxF par %% ~ nxF.
Owen
1
Qu'est - ce que ~nxdans %~nxFexactement?
Serge Rogatch
@stu, cela dit seulement que pour ~nxFla variable Fse transforme en un nom de fichier et une extension.
Serge Rogatch
Oui, donc effectivement, donnez-moi le nom de fichier + l'extension, sans le chemin - ce dont vous avez besoin pour faire le test dans le dossier cible et spécifier le nom du fichier cible. Le fait est que% F inclut le chemin et que vous ne le souhaitez pas.
Stu
207

Robocopy , ou «Robust File Copy», est une commande de réplication de répertoire en ligne de commande. Il a été disponible dans le cadre du Kit de ressources Windows à partir de Windows NT 4.0 et a été introduit en tant que fonctionnalité standard de Windows Vista, Windows 7 et Windows Server 2008.

   robocopy c:\Sourcepath c:\Destpath /E /XC /XN /XO

Pour élaborer (en utilisant les réponses Hydrargyrum, HailGallaxar et Andy Schmidt):

  • /E permet à Robocopy de copier récursivement les sous-répertoires, y compris les vides.
  • /XCexclut les fichiers existants avec le même horodatage, mais des tailles de fichier différentes. Robocopy les écrase normalement.
  • /XNexclut les fichiers existants plus récents que la copie dans le répertoire de destination. Robocopy les écrase normalement.
  • /XOexclut les fichiers existants plus anciens que la copie dans le répertoire de destination. Robocopy les écrase normalement.

Avec les classes Changed, Older et Newer exclues, Robocopy fait exactement ce que l'affiche originale veut - sans avoir besoin de charger un environnement de script.

Références: Technet , Wikipedia
Téléchargement depuis: Lien de téléchargement Microsoft (Dernière vérification du lien le 30 mars 2016)

Dr Bélisarius
la source
Par «exclure», voulez-vous dire «ignorer» ou «supprimer / supprimer»?
frappe aérienne du
@Andre Terra: Sautez, normalement. Si vous utilisez l'indicateur / MIR, cela peut les supprimer. Je n'ai pas testé ça.
Hydrargyrum
Avec / MIR, les fichiers qui n'existent pas dans la source sont effectivement supprimés. Mais lorsque vous utilisez également / XN et / XO, les fichiers qui existent aux deux endroits sont simplement ignorés (je ne sais pas si la taille est cochée). C'est idéal pour ma situation où j'ai besoin de copier une version plus récente ou plus ancienne de mon application mais où les tampons dateModified des bibliothèques que l'application utilise sont incorrects alors que les noms de fichiers eux-mêmes contiennent leur numéro de version.
Henno Vermeulen
Est-il nécessaire d'inclure /e? Et si vous utilisez à la /splace? Je ne veux pas d'un tas de sous-dossiers vides.
Arete le
48

La solution de Bélisaire est bonne.

Pour élaborer sur cette réponse légèrement laconique:

  • /E permet à Robocopy de copier récursivement les sous-répertoires, y compris les vides.
  • /XCexclut les fichiers existants avec le même horodatage, mais des tailles de fichier différentes. Robocopy les écrase normalement.
  • /XNexclut les fichiers existants plus récents que la copie dans le répertoire source. Robocopy les écrase normalement.
  • /XOexclut les fichiers existants plus anciens que la copie dans le répertoire source. Robocopy les écrase normalement.

Avec les classes Changed, Older et Newer exclues, Robocopy fait exactement ce que l'affiche originale veut - sans avoir besoin de charger un environnement de script.

Hydrargyrum
la source
46

Vous pouvez essayer ceci:

echo n | copy /-y <SOURCE> <DESTINATION>

-yinvite simplement avant d'écraser et nous pouvons diriger n vers toutes ces questions. Donc, cela ne ferait que copier des fichiers non existants. :)

sachin11
la source
2
Magnifiquement simple.
Holf
6
pourquoi répond-il à toutes les questions quand on ne pipe qu'une seule fois?
phuclv
Génial, je suis allé avec cette option. Avant de penser à la tuyauterie, j'ai recherché sur Google un paramètre qui me manquait et je suis tombé sur cette page. En essayant cette solution, j'ai remarqué que lors du piping, la copie active apparemment le paramètre / Y, c'est pourquoi / -Y doit être ajouté.
Andrew
2
@phuclv Il semble copy /-ysimplement supposer automatiquement Non une fois que stdin est à court d'entrée. Vous pouvez omettre le premier explicite n, ou y insérer un tube < nul, et la même chose se produit.
mwfearnley
6

Le voici sous forme de fichier batch:

@echo off
set source=%1
set dest=%2
for %%f in (%source%\*) do if not exist "%dest%\%%~nxf" copy "%%f" "%dest%\%%~nxf"
Gabe
la source
3

Je veux juste clarifier quelque chose de mes propres tests.

@Hydrargyrum a écrit:

  • / XN exclut les fichiers existants plus récents que la copie dans le répertoire source. Robocopy les écrase normalement.
  • / XO exclut les fichiers existants plus anciens que la copie dans le répertoire source. Robocopy les écrase normalement.

C'est en fait à l'envers. XN fait "eXclude Newer" les fichiers mais il exclut les fichiers qui sont plus récents que la copie dans le répertoire de destination . XO fait "eXclude Older", mais il exclut les fichiers qui sont plus anciens que la copie dans le répertoire de destination .

Bien sûr, faites vos propres tests, comme toujours.

GrêleGallaxar
la source
1
Est-ce une réponse à la question initiale ou un commentaire sur la réponse de quelqu'un d'autre?
ASGM
1
La réponse d'Hydrargyrum qui a +25 voix au moment de la rédaction est-elle une réponse à la question initiale, ou un commentaire sur la réponse de quelqu'un d'autre?
mo.
3

Il existe une façon étrange de faire cela avec xcopy:

echo nnnnnnnnnnn | xcopy /-y source target

Incluez simplement autant de n que de fichiers que vous copiez, et cela répondra à n à toutes les questions d'écrasement.

Adam dit - Réintégrer Monica
la source
En ce qui concerne copy, voir cette réponse , en particulier @mwfearnley comment: copy /-ysuppose automatiquement nune fois que stdin est épuisé, donc vous ne pouvez par exemple echo nqu'une seule fois et cela fonctionne toujours.
rsenna
3
robocopy src dst /MIR /XX

/ XX: eXclude les fichiers et répertoires "eXtra" (présents dans la destination mais pas dans la source). Cela empêchera toute suppression de la destination. (c'est la valeur par défaut)

be_good_do_good
la source
1

Robocopy peut être téléchargé ici pour les systèmes sur lesquels il n'est pas déjà installé. (Ie Windows Server 2003.)

http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=17657 (aucun redémarrage requis pour l'installation)

N'oubliez pas de définir votre chemin vers l'exe robocopy. Pour ce faire, cliquez avec le bouton droit de la souris sur "mon ordinateur"> propriétés> avancé> "Variables d'environnement", puis recherchez la variable système du chemin et ajoutez-la à la fin: "; C: \ Program Files \ Windows Resource Kits \ Tools" ou partout où vous installé. Assurez-vous de laisser les chaînes de variables de chemin qui sont déjà présentes et ajoutez simplement le chemin supplémentaire.

une fois le chemin défini, vous pouvez exécuter la commande suggérée par belisarius. Cela fonctionne très bien.

Greg
la source
1

Cela ne me permettra pas de commenter directement les messages incorrects - mais laissez-moi simplement avertir tout le monde que la définition des options / XN et / XO est INVERSÉE par rapport à ce qui a été publié dans les messages précédents.

L'option Exclure les fichiers plus anciens / plus récents est cohérente avec les informations affichées dans la journalisation de RoboCopy: RoboCopy effectuera une itération dans la SOURCE, puis indiquera si chaque fichier de la SOURCE est "PLUS ANCIEN" ou "PLUS NOUVEAU" que le fichier de la destination.

Par conséquent, / XO exclura les fichiers ANCIENS SOURCE (ce qui est intuitif), pas "plus anciens que la source" comme cela a été affirmé ici.

Si vous souhaitez copier uniquement des fichiers source nouveaux ou modifiés, mais évitez de remplacer des fichiers de destination plus récents, alors / XO est la bonne option à utiliser.

Andy Schmidt
la source
0

Une approche simple serait d'utiliser l'option / MIR, pour refléter les deux répertoires. Fondamentalement, il ne copiera que les nouveaux fichiers vers la destination. Dans la prochaine commande, remplacez la source et la destination par les chemins d'accès à vos dossiers, le script recherchera n'importe quel fichier avec des extensions.

robocopy <source directory> <destination directory> *.* /MIR
Ionut V.
la source
0

C'est ce qui a fonctionné pour moi. J'utilise ceci pour "ajouter" des fichiers à l'autre lecteur, sans écrasement.

Fichier batch: robocopy-missingfiles.bat

@echo off
echo Copying 
echo      "%1"
echo   to "%2"
echo.
echo Press Cntr+C to abort
Pause
echo.
@echo on
robocopy %1 %2 /Xo /XN /XC /J /SL /S /MT:8 /R:1 /W:1 /V /DCOPY:DAT /ETA /COPY:DATO /FFT /A-:SH /XD $RECYCLE.BIN "System Volume Information"

Exemple:

robocopy-missingfiles.bat f:\Working-folder\ E:\Backup-folder\

Faites un test avant la mise en œuvre.

Ramesh
la source