Comment copier une structure de répertoires mais inclure uniquement certains fichiers (en utilisant des fichiers batch Windows)

StackOverflow https://stackoverflow.com/questions/472692

Question

Comme le titre le dit, comment puis-je copier récursivement une structure de répertoires en n'incluant que quelques fichiers? E.g étant donné la structure de répertoire suivante:

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

Les fichiers data.zip et info.txt peuvent apparaître n'importe où dans la structure de répertoires. Comment copier la structure de répertoires complète, en n'incluant que les fichiers nommés data.zip et info.txt (tous les autres fichiers doivent être ignorés)?

La structure de répertoire obtenue devrait ressembler à ceci:

copy_of_folder1
  folder2
    folder3
      data.zip
      info.txt
    folder4
    folder5
      data.zip
Était-ce utile?

La solution

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: modification du paramètre / S en / E pour inclure les dossiers vides.

Autres conseils

Une solution alternative qui copie un fichier à la fois sans nécessiter 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 externe for génère toute combinaison de chemin possible du sous-répertoire dans SOURCE_DIR et du nom dans FILENAMES_TO_COPY . Pour chaque fichier existant, xcopy est appelé. FILE_INTERMEDIATE_DIR contient le chemin du sous-répertoire du fichier dans SOURCE_DIR , qui doit être créé dans DEST_DIR .

essayez de diriger 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 - il est donc sûr et rapide.

retirez -v pour un fonctionnement plus rapide, une fois que vous vous y êtes habitué.

Si Powershell est une option, vous pouvez le faire:

Copy-Item c:\sourcePath d:\destinationPath -filter data.zip -recurse

Le principal inconvénient est qu’il copie tous les dossiers, même s’ils sont vides, car aucun fichier ne correspond au filtre que vous spécifiez. Vous pourriez donc vous retrouver avec une arborescence pleine de dossiers vides, en plus des quelques dossiers contenant les fichiers que vous souhaitez.

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 ne peut également copier que des types de fichiers spécifiés ou des noms de fichiers sélectifs.

Toute amélioration est la bienvenue. :)

Avec find et cp uniquement:

mkdir /tmp/targetdir
cd sourcedir
find . -type f -name '*.zip' -exec cp -p --parents {} /tmp/targetdir ";"
find . -type f -name '*.txt' -exec cp -p --parents {} /tmp/targetdir ";"

Semblable à la solution de Paulius, mais les fichiers qui ne vous intéressent 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

Ce n’est que deux commandes simples, mais je ne le recommanderais pas, sauf si les fichiers que vous n’avez PAS besoin de copier sont petits. En effet, cela copiera TOUS les fichiers, puis supprimera ceux qui ne sont pas nécessaires à la copie.

xcopy /E /I folder1 copy_of_folder1
for /F "tokens=1 delims=" %i in ('dir /B /S /A:-D copy_of_files ^| find /V "info.txt" ^| find /V "data.zip"') do del /Q "%i"

Bien sûr, la deuxième commande est un peu longue, mais ça marche!

En outre, cette approche ne vous oblige pas à télécharger et à installer des outils tiers (Windows 2000+ BATCH dispose de suffisamment de commandes pour cela).

Sous Linux et d'autres systèmes UNIX, il est facile d'utiliser la commande tar .

$ tar cvf /tmp/full-structure.tar *data.zip *info.txt

Ensuite, vous êtes arrivé à la cible et:

$ tar xvf /tmp/full-structure.tar 

Bien sûr, vous pouvez diriger la sortie du premier tar vers le second, mais le voir fonctionner par étapes est plus facile à comprendre et à expliquer. Il me manque le cd nécessaire / nouveau / chemin / dans la commande suivante - je ne me souviens tout simplement pas comment le faire maintenant. J'espère que quelqu'un d'autre pourra l'ajouter.

$ tar cvf -  *data.zip *info.txt |  tar xvf - 

Tar (gnutar) est également disponible sur Windows, mais j'utiliserais probablement moi-même la méthode xcopy sur cette plate-forme.

XCOPY /S folder1\data.zip copy_of_folder1  
XCOPY /S folder1\info.txt copy_of_folder1

MODIFIER: si vous souhaitez conserver les dossiers vides (vous semblez devoir relire votre message), utilisez / E au lieu de / S.

À l'aide de l'interface de ligne de commande WinRAR, vous pouvez copier les noms de fichiers et / ou les types de fichiers dans une archive. Ensuite, vous pouvez extraire cette archive à l'emplacement de votre choix. Cela préserve la structure de fichier d'origine.

Je devais ajouter des fichiers d’image d’album manquants sur mon téléphone sans avoir à recopier la musique elle-même. Heureusement, la structure de répertoire était la même sur mon ordinateur et mon mobile!

j'ai utilisé:

   rar a -r C:\Downloads\music.rar X:\music\Folder.jpg
  • C: \ Downloads \ music.rar = Archive à créer
  • X: \ music \ = Dossier contenant des fichiers de musique
  • Folder.jpg = Nom du fichier que je voulais copier

Ceci a créé une archive avec tous les fichiers Folder.jpg dans les sous-répertoires appropriés.

Cette technique peut également être utilisée pour copier des types de fichiers. Si les fichiers avaient tous des noms différents, vous pouvez choisir d'extraire tous les fichiers dans un seul répertoire. Des paramètres de ligne de commande supplémentaires peuvent archiver plusieurs types de fichiers.

Plus d'informations sur ce lien très utile http: // cects.com/using-the-winrar-command-line-tools-in-windows/

Pour ceux qui utilisent Altap Salamander (gestionnaire de fichiers à 2 panneaux): dans les options du menu contextuel Copier, spécifiez simplement les noms de fichiers ou les masques. Facile.

Les expressions régulières, les paresseux et les opposés aux installations me conviennent, j’ai donc créé un fichier de commandes qui crée le répertoire et les copie avec les commandes DOS de vanilla. Cela semble laborieux, mais plus rapide pour moi que de travailler avec robocopy.

  1. Créez votre liste de fichiers source avec les chemins complets, y compris la lettre du lecteur, si nécessaire, dans un fichier texte.
  2. Activez les expressions régulières dans votre éditeur de texte.
  3. Ajoutez des guillemets doubles autour de chaque ligne en cas d'espaces - chaîne de recherche (. *) remplace la chaîne "1" , puis cliquez sur Tout remplacer
  4. .
  5. Créez deux lignes par fichier - une pour créer le répertoire, une pour copier le fichier (qqq sera remplacé par le chemin de destination) - chaîne de recherche (. *) remplace la chaîne md qqq \ 1 \ nxcopy \ 1 qqq \ 1 \ n et cliquez sur remplacer tout
  6. Supprimez le nom de fichier des chemins de destination & # 8211; rechercher \\ ([^ \\ ^ "] +)" \ n remplacer \\ "\ n
  7. Remplacez dans le chemin de destination (dans cet exemple, A: \ src et B: \ dest ). Désactivez les expressions régulières, recherchez qqq " A: \ src \ , remplacez B: \ dest \ et cliquez sur Tout remplacer.

md créera des répertoires imbriqués. copy se comporterait probablement de la même manière que xcopy dans cet exemple. Vous voudrez peut-être ajouter / Y à xcopy pour supprimer les confirmations d’écrasement. Vous vous retrouvez avec un fichier de commandes comme ceci:

md "B:\dest\a\b\c\"
xcopy "C:\src\a\b\c\e.xyz" "B:\dest\a\b\c\e.xyz"

répété pour chaque fichier de votre liste d'origine. Testé sur Win7.

Pour cela faire un glisser-déposer, utilisez Winzip avec une option de préservation de la structure de répertoires. Créez simplement un nouveau fichier .zip au niveau du répertoire qui sera votre racine et faites-y glisser les fichiers.

Pour copier tous les fichiers texte dans G: et conserver la structure de répertoires:

xcopy *.txt /s G:
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top