Как скопировать структуру каталогов, но включать только определенные файлы (с использованием пакетных файлов Windows)

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

Вопрос

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

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
Это было полезно?

Решение

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

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

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

Другие советы

Альтернативное решение, которое копирует один файл за раз и не требует 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 содержит путь к подкаталогу файла внутри DEST_DIR, который необходимо создать в <=>.

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

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

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

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

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

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

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

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

Этот скрипт с именем " 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 " ;. Он также может копировать только файлы определенного типа или отдельные имена файлов.

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

Только с 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 ";"

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

@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

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

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 достаточно команд).

В 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 на этой платформе.

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

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

Используя интерфейс командной строки 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/

Для тех, кто использует Altap Salamander (файловый менеджер из 2 панелей): во всплывающем окне «Параметры копирования» просто укажите имена файлов или маски. Легко.

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

<Ол>
  • Создайте свой список исходных файлов с полными путями, включая букву диска, если nec, в текстовом файле.
  • Включите регулярные выражения в текстовом редакторе.
  • Добавьте двойные кавычки вокруг каждой строки в случае пробелов - найдите строку (.*) заменить строку "\1" и нажмите "заменить все"
  • Создайте две строки для файла - одну для создания каталога, одну для копирования файла (qqq будет заменен на путь назначения) - найдите строку md qqq\1\nxcopy \1 qqq\1\n заменить строку \\([^\\^"]+)"\n и нажмите заменить все
  • Удалить имя файла из путей назначения & # 8211; поиск \\"\n заменить A:\src
  • Заменить в пути назначения (в этом примере B:\dest и qqq"A:\src\). Отключите регулярные выражения, выполните поиск B:\dest\ replace <=> и нажмите replace all.
  • md создаст вложенные каталоги. copy, вероятно, будет вести себя идентично xcopy в этом примере. Возможно, вы захотите добавить / Y в xcopy для подавления подтверждений перезаписи. Вы получите командный файл, например, так:

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

    повторяется для каждого файла в исходном списке. Протестировано на Win7.

    Для этого с помощью перетаскивания используйте winzip, есть опция сохранения структуры dir. Просто создайте новый .zip на уровне каталога, который будет вашим корневым каталогом, и перетащите файлы в него.

    Чтобы скопировать все текстовые файлы в G: и сохранить структуру каталогов:

    xcopy *.txt /s G:
    
    Лицензировано под: CC-BY-SA с атрибуция
    Не связан с StackOverflow
    scroll top