120 votes

Comment copier une structure de répertoire mais n'inclure que certains fichiers (en utilisant les fichiers batch de Windows)

Comme le titre l'indique, comment puis-je copier de manière récursive une structure de répertoire mais en n'incluant que certains fichiers. Par exemple, avec la structure de répertoire suivante :

folder1
  folder2
    folder3
      data.zip
      info.txt
      abc.xyz
    folder4
    folder5
      data.zip
      somefile.exe
      someotherfile.dll

Les dossiers data.zip et info.txt peuvent apparaître partout dans la structure du répertoire. Comment puis-je copier la structure complète du répertoire, mais n'inclure que les fichiers nommés data.zip et info.txt (tous les autres fichiers doivent être ignorés) ?

La structure du répertoire résultant devrait ressembler à ceci :

copy_of_folder1
  folder2
    folder3
      data.zip
      info.txt
    folder4
    folder5
      data.zip

189voto

aphoria Points 8128

Vous ne mentionnez pas s'il doit s'agir uniquement d'un lot, mais si vous pouvez utiliser ROBOCOPY essayez ceci :

ROBOCOPY C:\Source C:\Destination data.zip info.txt /E

EDIT : Changement du /S pour /E pour inclure les dossiers vides.

1 votes

Puis-je copier *.zip avec cette syntaxe ? J'ai essayé d'écrire simplement *.zip au lieu de data.zip, mais cela n'a pas copié les fichiers, seulement les dossiers. J'ai également essayé ?.zip

1 votes

@Niels Brinch Oui, vous devriez être en mesure de le faire. Quelle est la ligne de commande exacte que vous utilisez ?

1 votes

ROBOCOPY00 C:\Source C:\Destination *.zip /E

29voto

sakra Points 13373

Une solution alternative qui copie un fichier à la fois et ne nécessite pas ROBOCOPY :

@echo off
setlocal enabledelayedexpansion

set "SOURCE_DIR=C:\Source"
set "DEST_DIR=C:\Destination"
set FILENAMES_TO_COPY=data.zip info.txt

for /R "%SOURCE_DIR%" %%F IN (%FILENAMES_TO_COPY%) do (
    if exist "%%F" (
        set FILE_DIR=%%~dpF
        set FILE_INTERMEDIATE_DIR=!FILE_DIR:%SOURCE_DIR%=!
        xcopy /E /I /Y "%%F" "%DEST_DIR%!FILE_INTERMEDIATE_DIR!"
    )
)

L'instruction for externe génère toutes les combinaisons de chemins possibles du sous-répertoire dans SOURCE_DIR et le nom dans FILENAMES_TO_COPY . Pour chaque fichier existant, xcopy est invoqué. FILE_INTERMEDIATE_DIR contient le chemin du sous-répertoire du fichier au sein de SOURCE_DIR qui doit être créé dans DEST_DIR .

1 votes

J'avais besoin de copier toutes les photos des dossiers et sous-dossiers, ce lot script m'a aidé. J'ai juste changé la ligne set FILENAMES_TO_COPY=data.zip info.txt ci-dessus pour set FILENAMES_TO_COPY=*.jpg

0 votes

J'obtiens une erreur parce que le chemin du fichier comporte des espaces (SOURCE_DIR=" C:\Origin Test", DEST_DIR=" C:\Dest Test", error : Test"" était inattendu à ce moment-là). J'ai essayé de remplacer %var% par !var ! partout, mais sans succès. Avez-vous une idée de la façon de résoudre ce problème ? La structure entière est pleine de noms de dossiers avec des espaces.

1 votes

Essayez set "SOURCE_DIR=C:\Origin Test" et set "DEST_DIR=C:\Dest Test" . Notez l'emplacement des guillemets.

16voto

Gabe Rainbow Points 751

Essayez de passer la sortie de find (c'est à dire le chemin du fichier) dans cpio

find . -type f -name '*.jpg' | cpio -p -d -v targetdir/

cpio vérifie l'horodatage des fichiers cibles -- donc c'est sûr et rapide.

supprimez -v pour une opération plus rapide, une fois que vous vous y serez habitué.

3 votes

@Christian il a une dépendance sur cpio qui ne fait pas partie de l'installation standard.

7voto

Rhak Kahr Points 337

Merci aux réponses précédentes. :)

Ce script nommé "r4k4copy.cmd" :

@echo off
for %%p in (SOURCE_DIR DEST_DIR FILENAMES_TO_COPY) do set %%p=
cls
echo :: Copy Files Including Folder Tree
echo :: http://stackoverflow.com
rem     /questions/472692/how-to-copy
rem     -a-directory-structure-but-only
rem     -include-certain-files-using-windows
echo :: ReScripted by r4k4
echo.
if "%1"=="" goto :NoParam
if "%2"=="" goto :NoParam
if "%3"=="" goto :NoParam
setlocal enabledelayedexpansion
set SOURCE_DIR=%1
set DEST_DIR=%2
set FILENAMES_TO_COPY=%3
for /R "%SOURCE_DIR%" %%F IN (%FILENAMES_TO_COPY%) do (
if exist "%%F" (
set FILE_DIR=%%~dpF
set FILE_INTERMEDIATE_DIR=!FILE_DIR:%SOURCE_DIR%=!
xcopy /E /I /Y "%%F" "%DEST_DIR%!FILE_INTERMEDIATE_DIR!"
)
)
goto :eof
:NoParam
echo.
echo Syntax: %0 [Source_DIR] [Dest_DIR] [FileName]
echo Eg.   : %0 D:\Root E:\Root\Lev1\Lev2\Lev3 *.JPG
echo Means : Copy *.JPG from D:\Root to E:\Root\Lev1\Lev2\Lev3

Il accepte les variables "Source", "Destination", et "Nom de fichier". Il peut également copier uniquement le type de fichiers spécifié ou certains noms de fichiers.

Toute amélioration est la bienvenue. :)

4voto

Patrick Cuff Points 13362

Similaire à la solution de Paulius, mais les fichiers dont vous ne vous souciez pas ne sont pas copiés puis supprimés :

@echo OFF

:: Replace c:\temp with the directory where folder1 resides.
cd c:\temp

:: You can make this more generic by passing in args for the source and destination folders.
for /f "usebackq" %%I in (`dir /b /s /a:-d folder1`) do @echo %%~nxI | find /V "data.zip" | find /v "info.txt" >> exclude_list.txt
xcopy folder1 copy_of_folder1 /EXCLUDE:exclude_list.txt /E /I

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