Как скопировать файлы из подпапок

Обновлено: 04.07.2024

В разделе Примеры показан принцип использования этой команды.

Синтаксис

Параметры

Комментарии

Использование /z

Если вы потеряли подключение на этапе копирования (например, если сервер переходит в режим «вне сети»), то после повторного подключения Подключение возобновится. /z также отображает процент выполнения операции копирования для каждого файла.

Использование /y в переменной среды копикмд.

В переменной среды КОПИКМД можно использовать параметр /y . Эту команду можно переопределить с помощью /-и в командной строке. По умолчанию выводится запрос на перезапись.

Копирование зашифрованных файлов

Копирование зашифрованных файлов на том, который не поддерживает EFS, приводит к ошибке. Сначала расшифровать файлы или скопировать их на том, который поддерживает EFS.

Чтобы добавить файлы, укажите один файл для назначения, но несколько файлов для источника (то есть с помощью подстановочных знаков или формата file1 + file2 + файл3).

Значение по умолчанию для назначения

Если опустить назначение, команда xcopy скопирует файлы в текущий каталог.

Указание того, является ли назначение файлом или каталогом

Нажмите клавишу F, если хотите скопировать файл или файлы в файл. Нажмите клавишу D, если хотите скопировать файл или файлы в каталог.

Использование команды xcopy для установки атрибута архива для целевых файлов

Команда xcopy создает файлы с установленным атрибутом Archive, независимо от того, был ли этот атрибут задан в исходном файле. Дополнительные сведения об атрибутах файлов и attribсм. в разделе Дополнительные ссылки.

Сравнение xcopy и diskcopy

Если у вас есть диск, содержащий файлы в подкаталогах, и вы хотите скопировать его на диск, имеющий другой формат, используйте команду xcopy вместо команды diskcopy. Так как команда diskcopy копирует диски по дорожке, исходный и целевой диски должны иметь одинаковый формат. Команда xcopy не имеет этого требования. Используйте xcopy , если вам не нужна полная копия образа диска.

Коды выхода для команды xcopy

Для обработки кодов завершения, возвращаемых xcopy, используйте параметр ERRORLEVEL в командной строке If в пакетной программе. Пример пакетной программы, обрабатывающей коды завершения с помощью If, см. в разделе Дополнительные ссылки. В следующей таблице перечислены все коды выхода и их описание.

Примеры

1. чтобы скопировать все файлы и подкаталоги (включая все пустые подкаталоги) с диска A на диск B, введите:

2. чтобы включить в предыдущий пример все системные или скрытые файлы, добавьте параметр командной строки/h следующим образом:

3. чтобы обновить файлы в каталоге \репортс с файлами в каталоге \равдата, которые были изменены с 29 декабря 1993 г., введите:

4. чтобы обновить все файлы, существующие в \репортс в предыдущем примере, независимо от даты, введите:

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

Файл xcopy. out содержит список всех копируемых файлов.

6. чтобы скопировать каталог \кустомер и все подкаталоги в каталог \\публик\аддресс на сетевом диске H:, оставьте атрибут "только для чтения" и при создании нового файла в H: введите:

8. можно создать пакетную программу для выполнения операций xcopy и использовать пакет If для обработки кода выхода при возникновении ошибки. Например, в следующей пакетной программе для параметров источника и назначения xcopy используются заменяемые параметры:

Чтобы использовать предыдущую пакетную программу для копирования всех файлов в каталоге К:\пргмкоде и его подкаталогов на диск B, введите:

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

В предыдущем примере это конкретное значение исходного параметра .\ток *. yml копирует те же три файла, даже если их два символа пути . \ были удалены. Однако файлы не копируются, если из исходного параметра был удален подстановочный знак «звездочка», что делает его просто .\ток.ИМЛ.


' Параметры вызова из TC:
' %L "%T" []
' где необязательный параметр может принимать значения:
' 0 - если в файле-списке указана папка, а не файл, то вложенные файлы и папки
' копируются с сохранением относительной структуры (по умолчанию);
' 1 - копирование всех файлов в корень целевой папки;
' 2 - копирование с созданием полной стуктуры вложенных папок относительно
' корня диска
' Если 1-ый параметр указан пустым (""), то файл-список выбирается вручную
' Если 2-ой параметр указан пустым (""), то целевая папка выбирается вручную
'==============================================================================
Option Explicit
'===== Изменяемые параметры ===================================================
Const Overwrite = False 'Признак перезаписи существующих файлов
Const IgnorePrefix = "file://localhost/" 'Игнорируемый префикс
'==============================================================================
Dim FSO, FileList, TargetDir, Mess, Mess1, List, F, Errors, MessMode
Dim FilesAmount, FoldersAmount, CopyMode, Depth, i, oSA, CopyFlags, WSH

SetMess
Set oSA = CreateObject("Shell.Application")
Set WSH = CreateObject("WScript.Shell")
CheckParam
List = Split(FSO.OpenTextFile(FileList, 1).ReadAll, vbNewLine)
If Overwrite Then
CopyFlags = 16
Else
CopyFlags = 0
End If

Set Errors = CreateObject("Scripting.Dictionary")
If CopyMode = 2 Then
Set Depth = CreateObject("Scripting.Dictionary")
End If
FilesAmount = 0
FoldersAmount = 0
For Each F In List
F = Trim(F)
If F <> "" Then
If LCase(Left(F, Len(IgnorePrefix))) = LCase(IgnorePrefix) Then
F = Mid(F, Len(IgnorePrefix) + 1)
End If
F = GetPath(F)
On Error Resume Next
Copy F, TargetDir
On Error GoTo 0
End If
Next
If FilesAmount > 0 Then
Mess1 = Mess(6) & " " & FilesAmount & " " & Mess(7)
End If
If FoldersAmount > 0 Then
Mess1 = Mess1 & vbNewLine & Mess(6) & " " & FoldersAmount & " " & Mess(13)
End If
If (FilesAmount = 0) And (FoldersAmount = 0) Then
Mess1 = Mess(8)
End If
If Errors.Count > 0 Then
MessMode = 2
Else
MessMode = 3
End If
Mess1 = Mess1 & vbNewLine & JoinErr(Errors)
MessBox Mess1, MessMode

Sub CheckParam
If WScript.Arguments.Count = 0 Then
MessBox Mess(1), 1
Quit
End If
If WScript.Arguments.Count < 2 Then
MessBox Mess(2), 1
Quit
End If
FileList = WScript.Arguments(0)
TargetDir = WScript.Arguments(1)
Set FSO = CreateObject("Scripting.FileSystemObject")
If FileList = "" Then
FileList = OpenFile
Else
FileList = GetPath(FileList)
End If
If TargetDir = "" Then
TargetDir = OpenFolder
Else
TargetDir = GetPath(TargetDir)
End If
If Not FSO.FileExists(FileList) Then
MessBox Mess(3), 1
Quit
End If
If Not FSO.FolderExists(TargetDir) Then
MessBox Mess(4), 1
Quit
End If
If FSO.GetFile(FileList).Size = 0 Then
MessBox Mess(5), 1
Quit
End If
If WScript.Arguments.Count > 2 Then
CopyMode = WScript.Arguments(2)
If Not (CopyMode = 0 Or CopyMode = 1 Or CopyMode = 2) Then
MessBox Mess(11), 1
Quit
End If
Else
CopyMode = 0
End If
End Sub

Sub SetMess
Set Mess = CreateObject("Scripting.Dictionary")
Mess.Add 0, "Копирование из файла-списка"
Mess.Add 1, "Не указаны входные параметры!"
Mess.Add 2, "Указаны не все входные параметры!"
Mess.Add 3, "Файл-список не существует!"
Mess.Add 4, "Целевая папка не существует!"
Mess.Add 5, "Файл-список пустой!"
Mess.Add 6, "Успешно скопировано"
Mess.Add 7, "файлов."
Mess.Add 8, "Ничего не удалось скопировать."
Mess.Add 9, "Не удалось выполнить копирование"
Mess.Add 10, "по причине ошибки:"
Mess.Add 11, "Неправильно указан режим копирования!"
Mess.Add 12, "Успешно создано"
Mess.Add 13, "папок."
Mess.Add 14, "В целевой папке данный файл уже существует!"
Mess.Add 15, "Выбирете целевую папку"
Mess.Add 16, "Файл-список"
Mess.Add 17, "Ошибка не известна."
Mess.Add 18, "Введите путь к файлу-списку."
Mess.Add 19, "Введено несуществующее имя файла." & vbNewLine & "Нажмите ""OK"" для повторного ввода."
End Sub

Function MessBox(pMess, pMode)
Dim lIcon
Select Case pMode
Case 1 lIcon = vbCritical + vbOKOnly
Case 2 lIcon = vbExclamation + vbOKOnly
Case 3 lIcon = vbInformation + vbOKOnly
Case 4 lIcon = vbExclamation + vbOKCancel
End Select
MessBox = MsgBox(pMess, lIcon, Mess(0))
End Function

Function JoinErr(pDic)
Dim lKey
For Each lKey In pDic
JoinErr = JoinErr & vbNewLine & vbNewLine & _
Mess(9) & " """ & lKey & """ " & Mess(10) & _
vbNewLine & pDic(lKey)
Next
End Function

Sub Copy(pF, pTarget)
Dim lF, oF, lTarget, oNS
lTarget = pTarget
If Right(lTarget, 1) <> "\" Then
lTarget = lTarget & "\"
End If
If CopyMode = 2 Then
lTarget = CopyFolderStructure(lTarget, pF)
End If
If FSO.FileExists(pF) Then
If (Not Overwrite) And FSO.FileExists(lTarget & FSO.GetFile(pF).Name) Then
Errors.Add pF, Mess(14)
Else
CreateFoldersTree lTarget
Set oNS = oSA.NameSpace(lTarget)
oNS.CopyHere pF, CopyFlags
Set oNS = Nothing
If Err.Number <> 0 Then
Errors.Add pF, Err.Description
Else
If Not FSO.FileExists(lTarget & FSO.GetFile(pF).Name) Then
Errors.Add pF, Mess(17)
Else
FilesAmount = FilesAmount + 1
End If
End If
End If
End If
If FSO.FolderExists(pF) Then
CreateFoldersTree lTarget
Set oF = FSO.GetFolder(pF)
If (CopyMode = 0) Or (CopyMode = 2) Then
Set oNS = oSA.NameSpace(lTarget)
oNS.CopyHere pF, CopyFlags
Set oNS = Nothing
If Err.Number <> 0 Then
Errors.Add pF, Err.Description
Else
If Not FSO.FolderExists(lTarget & oF.Name) Then
Errors.Add pF, Mess(17)
Else
FoldersAmount = FoldersAmount + 1
End If
End If
End If
If CopyMode = 1 Then
For Each lF In oF.Files
If (Not Overwrite) And FSO.FileExists(lTarget & lF.Name) Then
Errors.Add lF.Path, Mess(14)
Else
Set oNS = oSA.NameSpace(lTarget)
oNS.CopyHere lF.Path, CopyFlags
Set oNS = Nothing
If Err.Number <> 0 Then
Errors.Add lF.Path, Err.Description
Else
If Not FSO.FileExists(lTarget & lF.Name) Then
Errors.Add lF.Path, Mess(17)
Else
FilesAmount = FilesAmount + 1
End If
End If
End If
Next
For Each lF In oF.SubFolders
Copy lF.Path, lTarget
Next
Set lF = Nothing
End If
Set oF = Nothing
End If
End Sub

Function CopyFolderStructure(pTarget, pPath)
Dim lPath
If FSO.FileExists(pPath) Then
lPath = FSO.GetParentFolderName(pPath) & "\"
Else
lPath = FSO.GetAbsolutePathName(pPath) & "\"
End If
Depth.RemoveAll
GetDepth lPath
CopyFolderStructure = pTarget
For i = Depth.Count To 1 Step -1
CopyFolderStructure = CopyFolderStructure & Depth(i) & "\"
Next
End Function

Sub CreateFoldersTree(pFolder)
Dim lParentFolder
If Not FSO.FolderExists(pFolder) Then
lParentFolder = FSO.GetParentFolderName(pFolder)
If Not FSO.FolderExists(lParentFolder) Then
CreateFoldersTree(lParentFolder)
End If
FSO.CreateFolder(pFolder)
End If
End Sub

Sub GetDepth(pPath)
Depth.Add Depth.Count + 1, FSO.GetFolder(pPath).Name
If FSO.GetDriveName(pPath) & "\" <> FSO.GetParentFolderName(pPath) Then
GetDepth FSO.GetParentFolderName(pPath)
End If
End Sub

Function OpenFile
Dim Dlg, DlgResult
On Error Resume Next
Set Dlg = CreateObject("UserAccounts.CommonDialog")
If Err.Number = 0 Then
On Error GoTo 0
Dlg.Filter = Mess(16) & " (*.*)|*.*"
Dlg.Flags = &H4 + &H8 + &H400 + &H1000 + &H80000
DlgResult = Dlg.ShowOpen
If DlgResult Then
OpenFile = Dlg.FileName
End If
Set Dlg = Nothing
If Not DlgResult Then
Quit
End If
Else
On Error GoTo 0
Do
Dlg = InputBox(Mess(18), Mess(0))
If Dlg = "" Then
Quit
Else
Dlg = GetPath(Dlg)
End If
If Not FSO.FileExists(Dlg) Then
Dlg = ""
DlgResult = MessBox(Mess(19), 4)
If DlgResult = vbCancel Then
Quit
End If
End If
Loop Until (Dlg <> "")
OpenFile = Dlg
End If
End Function

Function OpenFolder
Dim oF, lSelect
Set oF = oSA.BrowseForFolder(0, Mess(15), 16)
lSelect = Not (TypeName(oF) = "Nothing")
If lSelect Then
OpenFolder = oF.Self.Path
End If
Set oF = Nothing
If Not lSelect Then
Quit
End If
End Function

Function GetPath(pPath)
GetPath = FSO.GetAbsolutePathName(WSH.ExpandEnvironmentStrings(pPath))
End Function

Sub Quit
Set Errors = Nothing
Set Depth = Nothing
Set Mess = Nothing
Set FSO = Nothing
Set oSA = Nothing
Set WSH = Nothing
WScript.Quit
End Sub

В шапке скрипта можно по желанию изменить константу Overwrite значением True или False - признак перезаписи существующих файлов.

Параметры для разных вариантов использования:

* Копирование выделенных файлов\папок в противоположную панель ТС:

* Копирование файлов\папок из файла-списка в противоположную панель ТС:

* Копирование файлов\папок из файла-списка в указанную целевую папку:

* Копирование выделенных файлов\папок в указанную целевую папку:

* Копирование файлов\папок из файла-списка под курсором в указанную целевую папку:

* Копирование выделенных файлов\папок в выбираемую при запуске папку:

* Копирование файлов\папок из выбираемого при запуске файла-списка в выбираемую при запуске папку:

Не русскоязычные пользователи могут соотвествующим образом изменить процедуру SetMess.

Добавлено: Теперь, если второй параметр пустой (""), целевую папку можно указать вручную.

Добавлено: Теперь, если первый параметр пустой (""), файл-список можно указать вручную. Изменен способ копирования. Добавлен вариант копирования (2) с полным копированием структуры.

Добавлено: Теперь у представленных в файле-списке файлов\папок игнорируется префикс "file://localhost/".

Добавлено: Теперь в параметрах можно использовать переменные окружения.

Исправлено: Если первый параметр пустой (""), на Windows Vista ошибка не возникает, и путь к файлу-списку нужно вводить вручную.

Приветствуются комментарии с полезной информацией: уточнениями, дополнениями, вопросами. Очень хорошо, когда вы делитесь своим опытом. Ваш опыт и информация, могут быть полезны другим.
Категорически запрещено в комментариях использование ненормативной лексики (в том числе нецензурную речь). Комментарии со спамом и рекламой, не пройдут модерацию.
Все комментарии, проходят модерацию и публикуются только после рассмотрения и одобрения.

Команда COPY при работе в командной строке позволяет копировать один или несколько файлов. Команда имеет синтаксис: COPY[/D][/V][/N][/Y | /-Y][/Z][/L][/A | /B]источник[/A | /B][+ источник[/A | /B] [+ . ]][результат [/A | /B]]. Источником является имя копируемого файла, а результатом является каталог, в который будет помещена копия этого файла и/или имя создаваемого файла.

Для примера, создадим на диске «С» какой-нибудь файл (я создал текстовый файл «robot.txt»), а на диске «D» какую-нибудь папку (я создал папку «folder1»). Тогда команда для копирования файла «robot.txt» в папку «folder1» выглядит так: copy robot.txt d:\folder1

copy

Если необходимо скопировать файл, изменив при этом его имя, необходимо записать следующую команду: copy robot.txt d:\folder1\file.txt В этом случае, файл «robot.txt» будет скопирован в папку «folder1», но уже с именем «file.txt».

copy.

Для того чтобы скопировать все файлы с выбранным расширением, необходимо вместо названия файла поставить звездочку «*». Например, создадим на диске «С» какую-нибудь папку (я создал папку «papka») и скопируем в нее все текстовые файлы из папки «folder1», расположенной на диске «D». Команда будет иметь вид: copy d:\folder1\*.txt c:\papka

copy..

Если в качестве [результата] не указывать каталог, то команда copy скопирует файл (или файлы) и поместит их в текущем каталоге. При этом скопированные файлы будут иметь то же имя, дату и время создания, что и исходный файл. Например, создадим в папке «folder1», расположенной на диске «D» текстовый файл с именем «robot1.txt». После этого в командной строке изменим текущий каталог с «C:\>» на «C:\Papka». Тогда команда copy d:\folder1\robot1.txt скопирует файл «robot1.txt» из папки «folder1» и поместит его в текущем каталоге, т.е. в папку «papka», расположенную на диске «C». Причем, имя, дата и время создания скопированного файла будет идентично исходному файлу.

copy.

Для того чтобы скопировать все файлы из определенного каталога, необходимо вместо названия файла поставить звездочку «*» и вместо расширения файла поставить звездочку «*». Например, создадим в папке «folder1» несколько файлов, имеющих различные расширения (документ Word, архив Rar и т.д.). Тогда команда для копирования всех файлов из папки «folder1» на диск «C» будет выглядеть: copy d:\folder1\*.* c:\

copy.

  • LPT1 – LPT3 (параллельные порты).
  • COM1 – COM3 (последовательные порты).
  • CON (терминал, при выводе это экран компьютера, при вводе – клавиатура).
  • PRN (принтер).
  • AUX (устройство, подсоединяемое к последовательному порту 1).

Например, с помощью командной строки и команды «copy» можно создать текстовый файл и записать в него информацию: copy con f1.txt . Команда copy con f1.txt создаст текстовый файл «f1.txt» и скопирует в него символы, которые вы будете вводить с клавиатуры.

copy.

После ввода команды copy con f1.txt нажимаем Enter и вводим слова, которые необходимо сохранить (я ввел command com). После ввода необходимо поставить признак конца файла (нажать Ctrl+Z).
C помощью команды copy можно объединять несколько файлов в один файл. Например, создадим на диске «C» два файла f2.txt и f3.txt (файл f1.txt мы создали ранее) и запишем в эти файлы какую-нибудь информацию. Тогда команда copy f1.txt+f2.txt+f3.txt d:\f4.txt скопирует содержимое файлов «f1.txt», «f2.txt», «f3.txt» в файл «f4.txt», который будет автоматически создан на диске «D».

copy.

Если при объединении файлов не указывать файл - [результат], то вся информация будет сохранена в первом файле. Например, команда copy f1.txt+f2.txt+f3.txt добавит к содержимому файла f1.txt содержимое файлов f2.txt и f3.txt

copy.

copy2

Есть директория, в которой есть подпапки, и в этих подпапках есть еще подпапки. Цель: копирование всех файлов, из всех папок и подпапок, в другую директорию, избегая создания дерева директорий. И все это в терминале, естественно.


find /your_root_dir -type f | xargs cp your_target_dir

Чем -exec cp '<>' your_target_dir не угодил?


почему не угодил? есть же больше одного верного способа.

а что ты будешь делать с совпадающими именами файлов?

а что ты будешь делать с совпадающими именами файлов?

Есть же cp --backup=numbered !



Потому что xargs cp your_target_dir сделает: cp your_target_dir file1 file2 . то есть

есть же больше одного верного способа.

ваш способ не верен.

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

find /your_root_dir -type f | xargs cp your_target_dir

Но и это тоже плохо: если файлов по-настоящему много, может произойти переполнение строки аргументов. xargs -n1000 лучше, но тоже плохо если в именах файлов есть пробелы и прочий мусор.

xargs cp your_target_dir сделает: cp your_target_dir file1 file2


Зато не верно ваше:

если файлов по-настоящему много, может произойти переполнение строки аргументов.

xargs сделан был в том числе и для предотвращения этого. С появлением в стандарте posix у find опции -exec cmd +, большинство применений xargs стало не нужным, кроме возможности сделать указанную задачу — поместить аргумент у команды после считанных.

xargs сделан был в том числе и для предотвращения этого.

Это каким образом, интересно? Если, например, cp в моей системе собран принимать не более 1024 символов, как, по твоему предположению, ксаргс об этом узнает?


cp в моей системе собран принимать не более 1024 символов

Это как? В смысле, сам cp здесь вроде ни при чём, ARG_MAX для exec* же. А cp другие процессы, если не ошибаюсь, не запускает

Я, если честно, не в курсе, как устроен cp изнутри. Но на грабли с ксаргсом и переполнением наступал не раз.

Лол, и ведь посмотреть даже нельзя:


Подобный костыль - ярчайшее подтверждение наличия проблемы

Вы сами то приведенный url прочитали? Там честно предупреждали, что -i работает криво и давно юзать его не рекомендуется.


find /dir/where/ -exec cp --target-directory=DIRECTORY <> +

Так себе костыль, количество ругани будет впечатляющим:

Ну так надо добавить к вызову финда всякие -type f и прочее по вкусу и ситуации, а не тупо копировать всякий код с лора в рутовую консоль на проде :)


Воот. А народ тащится от минималистических однострочников. Даже вон запоминает подпорки типа "--target-directory=DIRECTORY" :) . Удручает.

Вы сами то приведенный url прочитали? Там честно предупреждали

Читал ли я, как именно в бизибоксе закостылили xargs и какими именно ограничениями и несовместимостями он отягощён? Ну разумеется, и каждый день перечитываю. Что вообще может быть интереснее и насущнее?


Читал ли я, как именно в бизибоксе закостылили xargs и какими именно ограничениями и несовместимостями он отягощён?

Эта проблема не имеет отношения к топику, но можно и об этом поговорить.

Ну разумеется, и каждый день перечитываю. Что вообще может быть интереснее и насущнее?

А почитать вообще бы вам не помешало. А то у вас странные представления о внутреннем устройcтве утилит. Маленькая подсказка:

если, например, cp в моей системе собран принимать не более 1024 символов,

Логически вытекает, что вообще ничего делать нельзя, вдруг у вашей cp там вообще 99?

Не знаю никого, ктобы запомнил про –target-directory=DIRECTORY кроме меня :) А я её запомнил потому, что она хорошо работает с find -exec и xargs, которые опять же я люблю а другие не очень и предпочитают циклы баша или что похуже.


Тут ранее бывал тоже один любитель xargs, который с удивлением узнал, что без -d '\n' юзать нельзя.

а другие не очень и предпочитают циклы баша или что похуже.

Дык, это позволяет сделать задачу хорошо, универсально, расширяемо, шаблонируемо под небольший изменения и т д. А где ещё есть это самое --target-dir ?

Его и с -d ‘\n’ юзать нельзя, по крайней пере с именами файлов.

Где мне надо, там везде есть. А там где нет - выдаст читаемую ошибку, что тоже важно.

А то у вас странные представления о внутреннем устройcтве утилит.

Да. Короткий эксперимент подтвердил, что я неправ. Но исходникам бизибокса на ночь все равно предпочту другое чтение :).


Его и с -d ‘\n’ юзать нельзя, по крайней пере с именами файлов.

Проблема в том, что утилит с аналогом -print0 шиш да маленько.

Ничего не понял. Этот ваш --target-dir, по-моему, ещё реже, чем -print0 встречается.

Читайте также: