Cómo copiar una estructura de directorios pero solo incluir ciertos archivos (usando archivos por lotes de Windows)


Como dice el título, ¿cómo puedo copiar recursivamente una estructura de directorios pero solo incluir algunos archivos? Por ejemplo, dada la siguiente estructura de directorios:

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

Los archivos datos.zip y info.txt puede aparecer en todas partes en la estructura de directorios. Cómo puedo copiar la estructura de directorios completa, pero solo incluir archivos con nombre data.zip e información.txt (todos los demás archivos deben ser ignorados)?

La estructura de directorios resultante debería tener este aspecto:

copy_of_folder1
  folder2
    folder3
      data.zip
      info.txt
    folder4
    folder5
      data.zip
Author: M4N, 2009-01-23

15 answers

No mencionas si tiene que ser solo por lotes, pero si puedes usar ROBOCOPY, prueba esto:

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

EDITAR: Se cambió el parámetro /S a /E para incluir carpetas vacías.

 134
Author: aphoria,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-05-22 18:04:47

Una solución alternativa que copia un archivo a la vez y no requiere 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!"
    )
)

La instrucción outer for genera cualquier posible combinación de ruta de subdirectorio en SOURCE_DIR y nombre en FILENAMES_TO_COPY. Para cada archivo existente se invoca xcopy. FILE_INTERMEDIATE_DIR contiene la ruta del subdirectorio del archivo dentro de SOURCE_DIR que necesita ser creada en DEST_DIR.

 26
Author: sakra,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-07-09 14:48:23

Pruebe la salida de tubería de find (es decir. la ruta del archivo) en cpio

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

Cpio comprueba la marca de tiempo en los archivos de destino so por lo que es seguro y rápido.

Remove-v para una operación más rápida, una vez que se acostumbre a ella.

 11
Author: Gabe Rainbow,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-12-18 21:26:09

Gracias A Las Respuestas Anteriores. :)

Este script llamado "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

Acepta variables de "Source", "Destination" y "FileName". También solo puede copiar el tipo especificado de archivos o nombres de archivos selectivos.

Cualquier mejora es bienvenida. :)

 7
Author: Rhak Kahr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-11-10 04:26:50

Si Powershell es una opción, puede hacer esto:

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

La principal desventaja es que copia todas las carpetas, incluso si terminarán vacías porque no hay archivos que coincidan con el filtro que especifique. Así que podría terminar con un árbol lleno de carpetas vacías, además de las pocas carpetas que tienen los archivos que desea.

 6
Author: Neil,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-03-16 17:12:50

Similar a la solución de Paulius, pero los archivos que no te importan no se copian y luego se eliminan:

@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
 4
Author: Patrick Cuff,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-01-23 14:10:38

Con find y cp solamente:

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 ";"
 4
Author: Rop,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-01-09 15:42:13

Eso son solo dos comandos simples, pero no lo recomendaría, a menos que los archivos que NO necesita copiar sean pequeños. Esto se debe a que esto copiará TODOS los archivos y luego eliminará los archivos que no sean necesarios en la copia.

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"

Claro, el segundo comando es un poco largo, ¡pero funciona!

Además, este enfoque no requiere que descargue e instale herramientas de terceros (Windows 2000+ BATCH tiene suficientes comandos para esto).

 3
Author: Paulius,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-01-23 13:33:55
XCOPY /S folder1\data.zip copy_of_folder1  
XCOPY /S folder1\info.txt copy_of_folder1

EDIT: Si desea conservar las carpetas vacías (que, al releer su publicación, parece que lo hace) use /E en lugar de /S.

 1
Author: gkrogers,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-01-23 12:45:38

Usando la interfaz de línea de comandos WinRAR, puede copiar los nombres de archivo y/o tipos de archivo a un archivo. Luego puede extraer ese archivo a la ubicación que desee. Esto preserva la estructura original del archivo.

Necesitaba agregar los archivos de imagen del álbum faltantes a mi teléfono móvil sin tener que volver a copiar la música en sí. Afortunadamente la estructura de directorios era la misma en mi ordenador y móvil!

He utilizado:

   rar a -r C:\Downloads\music.rar X:\music\Folder.jpg
  • C:\Downloads\music.rar = Archivo a ser creado
  • X:\music\ = Carpeta que contiene archivos de música
  • Carpeta.jpg = Nombre de archivo que quería copiar

Esto creó un archivo con toda la carpeta.archivos jpg en los subdirectorios adecuados.

Esta técnica también se puede usar para copiar tipos de archivos. Si todos los archivos tenían nombres diferentes, podría optar por extraer todos los archivos a un solo directorio. Los parámetros adicionales de la línea de comandos pueden archivar varios tipos de archivos.

Más información en este enlace muy útil http://cects.com/using-the-winrar-command-line-tools-in-windows /

 1
Author: Jim_Joat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-01-20 16:41:06

Bajo Linux y otros sistemas UNIX, usar el comando tar haría esto fácilmente.

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

Entonces usted cwd al objetivo y:

$ tar xvf /tmp/full-structure.tar 

Por supuesto, podría canalizar la salida del primer tar al 2do, pero verlo funcionar en pasos es más fácil de entender y explicar. Me falta el cd /to/new/path / necesario en el siguiente comando-simplemente no recuerdo cómo hacerlo ahora. Alguien más puede añadirlo, con suerte.

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

Tar (gnutar) también está disponible en Windows, pero probablemente usaría el método xcopy yo mismo en esa plataforma.

 1
Author: JohnP,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-20 15:28:52

Para aquellos que usan Altap Salamander (administrador de archivos de 2 paneles) : en las Opciones de la ventana emergente de copia, solo especifique los nombres de archivo o máscaras. Sencillo.

 1
Author: Hugo P,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-13 22:26:21

Estoy bien con las expresiones regulares, perezoso y reacio a las instalaciones, así que creé un archivo por lotes que crea el directorio y copia con comandos vanilla DOS. Parece laborioso pero más rápido para mí que trabajar en robocopy.

  1. Cree su lista de archivos de origen con rutas completas, incluida la letra de unidad si nec, en un archivo de texto.
  2. Activa expresiones regulares en tu editor de texto.
  3. Agregue comillas dobles alrededor de cada línea en caso de espacios - cadena de búsqueda (.*) reemplazar cadena "\1" y haga clic en reemplazar todo
  4. Cree dos líneas por archivo - una para crear el directorio, otra para copiar el archivo (qqq se reemplazará con la ruta de destino) - cadena de búsqueda (.*) reemplace cadena md qqq\1\nxcopy \1 qqq\1\n y haga clic en reemplazar todo
  5. Eliminar el nombre del archivo de las rutas de destino-buscar \\([^\\^"]+)"\n reemplazar \\"\n
  6. Reemplazar en la ruta de destino (en este ejemplo A:\src y B:\dest). Desactive las expresiones regulares, busque qqq"A:\src\ reemplazar B:\dest\ y haga clic en reemplazar todo.

Md creará directorios anidados. copy probablemente se comportaría de manera idéntica a xcopy en este ejemplo. Es posible que desee agregar /Y a xcopy para suprimir la confirmación de sobrescritura. Terminas con un archivo por lotes así:

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

Repetido para cada archivo en su lista original. Probado en Win7.

 0
Author: Chris,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-02-22 23:03:47

Para hacer esto con arrastrar y soltar use winzip hay una opción de preservar la estructura dir. Simplemente crea un nuevo .zip en el nivel de directorio que será su raíz y arrastre los archivos en.

 -1
Author: Gnoy Dav,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-09-10 11:10:41

Para copiar todos los archivos de texto a G: y preservar la estructura de directorios:

xcopy *.txt /s G:
 -1
Author: Osbert Snudge,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-01 01:44:58