Як скопіювати структуру каталогу, але включати лише певні файли (використовуючи пакетні файли Windows)


103

Як зазначається в заголовку, як я можу рекурсивно копіювати структуру каталогу, але включати лише деякі файли. Наприклад, з урахуванням такої структури каталогів:

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

Відповіді:


169

Ви не згадуєте, чи має бути лише пакетна, але якщо ви можете використовувати ROBOCOPY, спробуйте це:

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

EDIT: Змінено /Sпараметр, /Eщоб включити порожні папки.


Чи можна скопіювати * .zip цим синтаксисом? Я спробував просто написати * .zip замість data.zip, але він не копіював файли, а лише папки. Я також спробував? .Zip
Нільс Брінч

@Niels Brinch Так, ви повинні зробити це. Який саме командний рядок ви використовуєте?
афорія

1
РОБОКОПІЯ C: \ Джерело C: \ Місце призначення * .zip / E
Нільс Брінч

Дивно. Яку ОС ви використовуєте? Чи є у вас необхідні дозволи для файлів / папок? Я тільки тестував на Win 7 і *.zipпрацював на мене.
афорія

Дійсно !? Я також використовую Win 7. Коли я намагаюся, він просто не копіює жодних файлів. Тільки папки. Я спробую ще раз. (поки ми на це, який синтаксис включає більше * .zip - скажімо * .zip та * .jpg.
Нільс Брінч,

29

Альтернативне рішення, яке копіює один файл одночасно і не вимагає РОБОКОПІЇ:

@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!"
    )
)

Зовнішній для оператора формує будь-яку можливу комбінацію шляху підкаталогу в SOURCE_DIRі ім'я в FILENAMES_TO_COPY. Для кожного наявного файлу викликається xcopy. FILE_INTERMEDIATE_DIRвміщує шлях до підкаталогу до файлу, в межах SOURCE_DIRякого потрібно створити DEST_DIR.


1
Мені потрібно було скопіювати всі фотографії з папок і папок, цей пакетний сценарій допоміг. Щойно змінив рядок set FILENAMES_TO_COPY=data.zip info.txtвищеset FILENAMES_TO_COPY=*.jpg
Kai Noack

Я отримую помилку, оскільки на шляху файлу є пробіли (SOURCE_DIR = "C: \ Origin Test", DEST_DIR = "C: \ Dest Test", помилка: "" Тест "" в цей момент був несподіваним). Я намагався змінити% var% на! Var! скрізь, але без успіху. Будь-які підказки, як вирішити це? Вся структура наповнена іменами папок з пробілами.
ricardo.scholz

1
Спробуйте set "SOURCE_DIR=C:\Origin Test"і set "DEST_DIR=C:\Dest Test". Зверніть увагу на розміщення подвійних лапок.
сакра

13

спробуйте констатувати вихідний файл пошуку (тобто шлях до файлу) в cpio

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

cpio перевіряє часові позначки на цільових файлах - так це безпечно і швидко.

видаліть -v для швидшого використання, як тільки ви звикнете до нього.


2
@Christian має залежність від cpio, який не є частиною стандартної установки.
Crashworks

8

Якщо Powershell - це варіант, ви можете зробити це:

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

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


Запустивши це вдруге, змінить призначення. (Він розміщує файли в підпапках.) Якщо ви запитаєте мене, це дурна поведінка. Вам потрібно буде запуститись rm -r -ErrorAction:SilentlyContinue d:\destinationPathперед копіюванням, щоб виправити це.
МакотоЕ

7

Завдяки попереднім відповідям. :)

Цей скрипт з назвою "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

Він приймає змінну "Джерело", "Місце призначення" та "Ім'я файлу". Він також може лише копіювати вказаний тип файлів або вибіркові назви файлів.

Будь-яке поліпшення вітається. :)


5

Лише для пошуку та копіювання:

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

Подібно до рішення Пауліуса, але файли, які вас не цікавлять, не копіюються та видаляються:

@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

Щоб скопіювати всі текстові файли в G: та зберегти структуру каталогу:

xcopy *.txt /s G:

чи може це працювати рекурсивно, як копіювання всього .txt з підпапок та збереження структури каталогів відносно базового каталогу?
Мікка

3

Це лише дві прості команди, але я б не рекомендував цього, якщо тільки файли, які вам НЕ потрібно копіювати, є невеликими. Це тому, що це скопіює ВСІ файли, а потім видалить файли, які не потрібні.

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 має достатньо команд для цього).


Дуже дякую. Як ви вже згадували, це не ідеально, тому що (у моєму випадку) файли, які потрібно скопіювати, зазвичай невеликі, тоді як файли, які не слід копіювати, є більшими (і їх може бути багато).
M4N

2

У Linux та інших системах UNIX використання tarкоманди може зробити це легко.

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

Тоді ви будете робити мету і:

$ tar xvf /tmp/full-structure.tar 

Звичайно, ви можете передати висновок з першого дьогтю у другий, але побачити, як він працює поетапно, простіше зрозуміти та пояснити. Мені не вистачає потрібного CD / to / new / path / у наступній команді - я просто не пам'ятаю, як це зробити зараз. Хтось ще може його додати, сподіваємось.

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

Тар (гнутар) також доступний і в Windows, але, мабуть, я сам би використовував цей xcopyметод на цій платформі.


tar cvf /tmp/full-structure.tar ** / data.zip ** / info.txt працював на мене
ssinganamalla

І "tar cvf /tmp/full-structure.tar ** / data.zip ** / info.txt", і "tar cvf /tmp/full-structure.tar * data.zip * info.txt" дали мені 3 помилки : (1) "tar: * data.zip: Не вдається статистика: Немає такого файлу чи каталогу", (2) "tar * info.txt: Неможливо стати: Немає такого файлу чи каталогу", (3) "tar: Вихід із стан відмови через попередні помилки ". З якої папки я все це роблю? Я не розумію цього методу.
користувач1271772

Питання говорить WINDOWS
Anfelipe

У Win10 є WSL, що робить це дійсним. смола доступна в Windows 20+ років, а використання труби працювало з часів MS-DOS. У будь-якому середовищі оболонки важливе значення має PWD. PWD - теперішній робочий каталог. Я визнаю, це рішення менше для кінцевих користувачів і більше для споживачів енергії або програмістів.
JohnP

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

РЕДАКТУВАННЯ: Якщо ви хочете зберегти порожні папки (які, начебто, перечитавши вашу публікацію, начебто), використовуйте / E замість / S.


1
це не зберігає структуру папок.
Павлій

Параметр / E зберігає структуру папок, включаючи створення порожніх папок, якщо це необхідно. Ім'я файлу також працює з підстановкою (наприклад, папка1 \ *. Zip). Я отримую "Помилку файлу не знайдено" лише тоді, коли передаю йому повне ім'я файлу, яке не існує (у такому випадку я отримую "Файл не знайдено - xxx.xxx 0 файлів, скопійованих". Коли я надаю йому шаблон який не повертає жодних файлів (наприклад, папка1 \ *. zzz), я просто отримую "0 файлів (* s) скопійовані".
gkrogers

1

За допомогою інтерфейсу командного рядка 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/


1

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


0

Мені добре з регулярними виразами, ледачими і неприязними до встановлень, тому я створив пакетний файл, який створює каталог і копіює ванільні команди DOS. Здається для мене трудомістким, але швидшим, ніж розробка роботоскопії.

  1. Створіть свій список вихідних файлів із повними шляхами, включаючи літеру диска, якщо не, у текстовому файлі.
  2. Увімкніть регулярні вирази у текстовому редакторі.
  3. Додайте подвійні лапки навколо кожного рядка у випадку пробілів - пошуковий рядок (.*)замінить рядок "\1"та натисніть кнопку Замінити всі
  4. Створіть два рядки на файл - один для створення каталогу, один для копіювання файлу (qqq буде замінено на шлях призначення) - пошуковий рядок (.*)замінить рядок md qqq\1\nxcopy \1 qqq\1\nта натисніть кнопку Замінити всі
  5. Видаліть ім’я файлу з пунктів призначення - пошук \\([^\\^"]+)"\nзамініть\\"\n
  6. Замініть шлях до пункту призначення (у цьому прикладі A:\srcта B:\dest). Вимкніть регулярні вирази, знайдіть qqq"A:\src\заміну B:\dest\та натисніть кнопку Замінити всі.

md створить вкладені каталоги. У цьому прикладі копія, ймовірно, поводитиметься однаково з 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.


-1

Щоб зробити це за допомогою перетягування, використовуйте winzip, є параметр збереження структури dir. Просто створіть новий .zip на рівні каталогу, який буде вашим коренем, і перетягніть файли в.


Дякую, але я шукав рішення, яке потрібно використовувати з файлів скриптів (пакетних). Отже, без перетягування ...
M4N
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.