Comme le titre le dit, comment puis-je copier récursivement une structure de répertoires en n'incluant que certains 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 partout dans la structure de répertoires. Comment puis-je copier la structure de répertoires complète, mais inclure uniquement les fichiers nommés data.Zip et info.txt (tous les autres fichiers doivent être ignorés)?
La structure de répertoire résultante devrait ressembler à ceci:
copy_of_folder1
folder2
folder3
data.Zip
info.txt
folder4
folder5
data.Zip
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: Changé le /S
paramètre sur /E
pour inclure des dossiers vides.
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 externe for génère toute combinaison de chemin possible du sous-répertoire dans SOURCE_DIR
et nom en 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 la sortie de piping 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 serez 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 finiront par être vides, car aucun fichier ne correspond au filtre que vous spécifiez. Ainsi, vous pourriez 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 de "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, l’utilisation de la commande tar
suffirait facilement.
$ tar cvf /tmp/full-structure.tar *data.Zip *info.txt
Ensuite, vous êtes arrivé à la cible et:
$ tar xvf /tmp/full-structure.tar
Vous pouvez bien sûr diriger la sortie du premier goudron 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 plus comment faire maintenant. Quelqu'un d'autre peut l'ajouter, espérons-le.
$ 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.
À 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.
J'avais besoin d'ajouter des fichiers d'image d'album manquants sur mon téléphone portable 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
Cela 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 de la copie, spécifiez simplement les noms de fichiers ou les masques. Facile.
XCOPY /S folder1\data.Zip copy_of_folder1
XCOPY /S folder1\info.txt copy_of_folder1
EDIT: Si vous souhaitez conserver les dossiers vides (vous semblez devoir relire votre message), utilisez/E au lieu de/S.
Je vais bien avec les expressions régulières, paresseux et peu enclin aux installations, alors j’ai créé un fichier de commandes qui crée le répertoire et les copie avec les commandes de Vanilla DOS. Cela semble laborieux mais plus rapide pour moi que de travailler avec Robocopy.
(.*)
Remplace la chaîne "\1"
Et cliquez sur Remplacer tout.(.*)
, Remplacez la chaîne md qqq\1\nxcopy \1 qqq\1\n
, Puis cliquez sur Remplacer tout.\\([^\\^"]+)"\n
remplacez \\"\n
A:\src
Et B:\dest
). Désactivez les expressions régulières, recherchez qqq"A:\src\
, Remplacez B:\dest\
, Puis cliquez sur Remplacer tout.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 batch 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.