1

У меня есть файловая иерархия, как это:

RootDir
  /A
    /fileA.txt
  /B
    /C
       /fileC.txt
    /fileB.txt
  /otherFile1.txt
  /otherFile2.txt

Я хотел бы скопировать только подкаталоги (т. Е. A , B) и все, что находится под ними (имеется в виду, что я хочу, чтобы все было скопировано, КРОМЕ otherFile1.txt и otherFile2.txt)

Под корневым каталогом находится более 2 папок и 2 файла, поэтому я бы не стал указывать каждый из них по имени.

Какие-либо предложения?

6 ответов6

2

Вы можете использовать комбинацию for /f, xcopy и dir для выполнения этой задачи:

cd SOURCE
for /F "delims=" %a in ('dir /B /AD') do @xcopy /E "%a" "DESTINATION\%a\"

Как это устроено:

  • После входа в каталог SOURCE команда dir /B /AD выводит список всех каталогов (/AD), один за другим (/B).

  • for /F "delims=" %a in ('...') do проходит через выходные данные команды ... , устанавливает переменную %a в следующую строку вывода и выполняет все, что следует do .

    Здесь delims= гарантирует, что переменная содержит содержимое всей строки. Без него %a будет содержать символы только до первого пробела.

  • xcopy /E "%a" "DESTINATION\%a\" копирует каталог, в настоящее время указанный в %a в папку с тем же именем в каталоге DESTINATION . Ключ /E также копирует содержимое каталога. 1

    Указание имени каталога в месте назначения имеет важное значение. Без этого fileA.txt будет скопирован в DESTINATION\fileA.txt (а не в DESTINATION\A\fileA.txt).

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

Если эта команда будет использоваться внутри пакетного файла, все знаки процента должны быть экранированы вторым знаком процента, то есть %a становится %%a .


1 /E копирует пустые каталоги. Если это нежелательно, вы можете использовать /S вместо.

2

Похоже на ответы Денниса и Дэвида Руманна, но вместо FOR /F используется цикл FOR /D.

for /d %F in (rootFolderPath\*) do @xcopy /e /i "%F" "destinationPath\%~nxF"
1

Наилучший способ, который я могу придумать, - это использовать переключатель «/create» в Robocopy, который копирует только всю структуру папок, и "только файлы 0 длины" - что, я уверен, приведет к исключению всех ваших файлов.

Robocopy /e /create \(исходный путь к папке A) \(целевой путь)

Robocopy /e /create \(исходный путь к папке B) \(целевой путь)

Вы также можете (если они имеют одинаковые типы файлов или небольшое количество известных типов файлов) использовать переключатель "Исключить файл" «/xf» и подстановочные знаки для типов файлов, например:

Robocopy /e (исходный путь к папке A) (целевой путь) /xf * .txt

Robocopy /e (исходный путь к папке B) (целевой путь) /xf * .txt

1

Подобные вещи просты с оболочкой Unix. Вот как вы можете сделать это с моей собственной оболочкой Hamilton C (включая бесплатную версию. Вы можете сделать что-то подобное с Cygwin bash хотя это может быть немного сложнее. Это скопирует все подкаталоги, но только подкаталоги RootDir и их содержимое в DestinationDir.

cd RootDir
cp ``ld -1`` DestinationDir

ld - псевдоним для ls котором перечислены только каталоги. Параметр -1 означает вывод результатов в одном столбце, по одной записи на строку. Двойные кавычки означают подстановку команд по очереди, гарантируя, что это будет работать, даже если в некоторых именах подкаталогов есть пробелы.

Вот скриншот, показывающий, как это работает. Обратите внимание, что он копирует все, кроме файла hello.txt в корне. Все подкаталоги и их содержимое скопированы. Опция ls -r означает рекурсивный.

Копировать только подкаталоги, используя оболочку Hamilton C

1

Собственное решение Windows CMD. Скопируйте только подпапки (и их содержимое) из RootDir.

for /f "delims=" %%A in ('dir RootDir /a:d /b') do xcopy %%A DestDir /e /i
0

Как отметил другой пользователь в комментариях, самое короткое решение, которое выполняет то, что пытается сделать ОП, это просто:

xcopy /t /e

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .