Как скопировать структуру каталогов, но включить только определенные файлы (используя пакетные файлы Windows) - PullRequest
91 голосов
/ 23 января 2009

Как видно из названия, как я могу рекурсивно копировать структуру каталогов, но включать только некоторые файлы. Например, с учетом следующей структуры каталогов:

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

Файлы data.zip и info.txt могут появляться везде в структуре каталогов. Как я могу скопировать всю структуру каталогов, но включить только файлы с именами data.zip и info.txt (все остальные файлы следует игнорировать)?

Полученная структура каталогов должна выглядеть следующим образом:

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

Ответы [ 15 ]

148 голосов
/ 23 января 2009

Вы не упоминаете, должен ли он быть только пакетным, но если вы можете использовать ROBOCOPY, попробуйте это:

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

РЕДАКТИРОВАТЬ: изменен параметр /S на /E для включения пустых папок.

29 голосов
/ 09 июля 2009

Альтернативное решение, которое копирует один файл за раз и не требует 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!"
    )
)

Внешний оператор for генерирует любую возможную комбинацию пути подкаталога в SOURCE_DIR и имени в FILENAMES_TO_COPY. Для каждого существующего файла вызывается xcopy. FILE_INTERMEDIATE_DIR содержит путь к подкаталогу файла в SOURCE_DIR, который необходимо создать в DEST_DIR.

11 голосов
/ 19 декабря 2012

попробуйте скопировать вывод find (т.е. путь к файлу) в cpio

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

cpio проверяет временную метку на целевых файлах, поэтому это безопасно и быстро.

удалите -v для более быстрой операции, как только вы к этому привыкнете.

7 голосов
/ 16 марта 2015

Если Powershell является опцией, вы можете сделать это:

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

Основным недостатком является копирование всех папок, даже если они окажутся пустыми, поскольку ни один файл не соответствует указанному вами фильтру. Таким образом, вы можете получить дерево, полное пустых папок, в дополнение к нескольким папкам, в которых есть нужные вам файлы.

7 голосов
/ 10 ноября 2011

Благодаря предыдущим ответам. :)

Этот скрипт с именем "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

Принимает переменные "Source", "Destination" и "FileName". Он также может копировать только файлы определенного типа или отдельные имена файлов.

Любые улучшения приветствуются. :)

5 голосов
/ 09 января 2014

Только с find и 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 ";"
4 голосов
/ 23 января 2009

Аналогично решению Паулюса, но файлы, которые вас не интересуют, не копируются, а затем удаляются:

@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
3 голосов
/ 23 января 2009

Это всего лишь две простые команды, но я бы не рекомендовал это, если только файлы, которые вам НЕ нужно копировать, имеют небольшой размер. Это потому, что это скопирует ВСЕ файлы, а затем удалит файлы, которые не нужны в копии.

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"

Конечно, вторая команда довольно длинная, но она работает!

Кроме того, этот подход не требует загрузки и установки каких-либо сторонних инструментов (для пакета Windows 2000+ BATCH достаточно команд).

2 голосов
/ 18 апреля 2013

В Linux и других системах UNIX это легко сделать с помощью команды tar.

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

Тогда вы подойдете к цели и:

$ tar xvf /tmp/full-structure.tar 

Конечно, вы могли бы перенаправить вывод из первого tar во второй, но увидеть, как он работает поэтапно, легче понять и объяснить. Мне не хватает необходимого cd / to / new / path / в следующей команде - я просто не помню, как это сделать сейчас. Надеюсь, кто-то еще может это добавить.

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

Tar (gnutar) также доступен в Windows, но я, вероятно, сам использую метод xcopy на этой платформе.

1 голос
/ 20 января 2016

Используя интерфейс командной строки WinRAR, вы можете копировать имена файлов и / или типы файлов в архив. Затем вы можете извлечь этот архив в любое место, которое вам нравится. Это сохраняет исходную структуру файла.

Мне нужно было добавить отсутствующие файлы изображений альбомов в мой мобильный телефон без необходимости переписывать музыку. К счастью, структура каталогов была одинаковой на моем компьютере и мобильном устройстве!

Я использовал:

   rar a -r C:\Downloads\music.rar X:\music\Folder.jpg
  • C: \ Downloads \ music.rar = Архив, который будет создан
  • X: \ music \ = Папка с музыкальными файлами
  • Folder.jpg = Имя файла, который я хотел скопировать

При этом был создан архив со всеми файлами Folder.jpg в соответствующих подкаталогах.

Этот метод также может использоваться для копирования типов файлов. Если все файлы имеют разные имена, вы можете выбрать извлечение всех файлов в один каталог. Дополнительные параметры командной строки могут архивировать файлы нескольких типов.

Больше информации в этой очень полезной ссылке http://cects.com/using-the-winrar-command-line-tools-in-windows/

...