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

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

Pregunta

Como dice el título, ¿cómo puedo copiar recursivamente una estructura de directorio 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 data.zip e info.txt pueden aparecer en todas partes en la estructura del directorio. ¿Cómo puedo copiar la estructura completa del directorio, pero solo incluir archivos llamados data.zip e info.txt (todos los demás archivos deben ignorarse)?

La estructura de directorios resultante debería verse así:

copy_of_folder1
  folder2
    folder3
      data.zip
      info.txt
    folder4
    folder5
      data.zip
¿Fue útil?

Solución

No menciona si tiene que ser solo por lotes, pero si puede usar ROBOCOPY , intente esto:

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

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

Otros consejos

Una solución alternativa que copia un archivo a la vez y no requiere ROBOCOPIA:

@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 for externa genera cualquier combinación de ruta posible del subdirectorio en SOURCE_DIR y el 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 debe crearse en DEST_DIR .

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, por lo que es seguro y rápido.

elimina -v para una operación más rápida, una vez que te acostumbres.

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 terminan vacías porque ningún archivo coincide con el filtro que especifique. Por lo tanto, podría terminar con un árbol lleno de carpetas vacías, además de las pocas carpetas que tienen los archivos que desea.

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 " Origen " ;, " Destino " ;, y " FileName " ;. También solo puede copiar tipos específicos de archivos o nombres de archivos selectivos.

Cualquier mejora es bienvenida. :)

Solo con find y cp:

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 ";"

Similar a la solución de Paulius, pero los archivos que no le interesan 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

Son solo dos comandos simples, pero no lo recomendaría, a menos que los archivos que NO necesite copiar sean pequeños. Esto se debe a que esto copiará TODOS los archivos y luego eliminará los archivos que no son 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 bastante largo, ¡pero funciona!

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

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

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

Luego, iría al objetivo y:

$ tar xvf /tmp/full-structure.tar 

Por supuesto, puede canalizar la salida del primer alquitrán al segundo, 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 agregarlo, 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.

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

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

Usando la interfaz de línea de comandos de 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 conserva la estructura del archivo original.

Necesitaba agregar los archivos de imagen de álbum que faltaban a mi teléfono móvil sin tener que volver a copiar la música. ¡Afortunadamente, la estructura del directorio era la misma en mi computadora y en mi dispositivo móvil!

Utilicé:

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

Esto creó un archivo con todos los archivos Folder.jpg en los subdirectorios adecuados.

Esta técnica también se puede utilizar para copiar tipos de archivos. Si todos los archivos tienen nombres diferentes, puede optar por extraer todos los archivos a un solo directorio. Los parámetros adicionales de la línea de comandos pueden archivar múltiples tipos de archivos.

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

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

Estoy bien con expresiones regulares, perezosas y aversas a las instalaciones, así que creé un archivo por lotes que crea el directorio y las copias con los comandos de DOS de vainilla. 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 es necesario, en un archivo de texto.
  2. Active las expresiones regulares en su editor de texto.
  3. Agregue comillas dobles alrededor de cada línea en caso de espacios: busque la cadena (. *) reemplace la cadena " \ 1 " y haga clic en reemplazar todo
  4. Cree dos líneas por archivo: una para crear el directorio y otra para copiar el archivo (qqq se reemplazará con la ruta de destino) - busque la cadena (. *) reemplace la cadena md qqq \ 1 \ nxcopy \ 1 qqq \ 1 \ n y haga clic en reemplazar todo
  5. Eliminar el nombre de archivo de las rutas de destino & # 8211; buscar \\ ([^ \\ ^ "] +) " \ n reemplazar \\"\n
  6. Reemplazar en la ruta de destino (en este ejemplo A: \ src y B: \ dest ). Desactiva las expresiones regulares, busca qqq " A: \ src \ reemplaza B: \ dest \ y haz clic en reemplazar todo.

md creará directorios anidados. copia probablemente se comportaría de manera idéntica a xcopy en este ejemplo. Es posible que desee agregar / Y a xcopy para suprimir las confirmaciones de sobrescritura. Terminas con un archivo por lotes como este:

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.

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

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

xcopy *.txt /s G:
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top