Как скопировать структуру каталогов, но включать только определенные файлы (с использованием пакетных файлов Windows)
-
19-08-2019 - |
Вопрос
Как сказано в заголовке, как я могу рекурсивно скопировать структуру каталогов, но включать только некоторые файлы.Например, учитывая следующую структуру каталогов:
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. Кажется трудоемким, но быстрее для меня, чем отработка робокопии.
<Ол>(.*)
заменить строку "\1"
и нажмите "заменить все" md qqq\1\nxcopy \1 qqq\1\n
заменить строку \\([^\\^"]+)"\n
и нажмите заменить все \\"\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: