Как скопировать файлы из разных папок в одну
Перейти к содержимому

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

  • автор:

Как быстро достать все файлы из кучи папок?

Есть куча папок. В них ещё куча папок. В них файлы, c ещё кучей папок. Одним словом — срач. Как мне все файлы из всех этих папок достать, и переместить в одну? Я сперва подумал, что надо просто в поиск вбить точку (ну типа у каждого же файла есть расширение, соответственно и точка в названии), и всё переместить, но оказалось, что так не все файлы нашлись. То есть, видимо, в этой помойке есть и файлы вообще без расширений, и они мне тоже нужны. В общем, кто знает метод — помогите пожалуйста)

Total Commander → Ctrl+B (показать файлы без каталогов) → Ctrl+A (выделить всё) → Ctrl+X (вырезать) → Ctrl+V (вставить)

Вот это, только советую не вырезать, а скопировать. А то мало ли что. И при копировании не забыть нажать options > overwrite options > 5. auto rename copied.
Но я бы сильно не советовал делать это ибо будет бардак.

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

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

сделать резервные копии всех жестких дисков,

Верно, нужно иметь резервные копии всех важных данных

обзвонить родственников на случай сердечного приступа.

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

Как раз хотел написать.

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

Эти красные глаза я узнаю из тысячи

Почему >? Это же перенаправление потока, которое тупо в консоль или из консоли. Раньше нужно было | использовать.
И вообще работать не будет. Минимум надо %1 в move и оформить батником.
Плюс в конце дир тебе выдаст сводку общему объему, там был еще параметр чтобы чистый список выдавал файла.
EDIT: Во, dir /s /b дает нормальный список файлов с полными путями.

Ещё исключить папки и передать вывод в xargs. то есть, for:
for /F "delims==" %%F in (‘dir ".\in\" /A-D /B /S’) do xcopy "%%F" ".\out\"
Или лучше без dir:
for /R ".\in\" %%F in (*) do xcopy "%%F" ".\out\"
Но это лишь разминка для ума (получается неудобно и ещё нужна обработка дубликатов).

он же написал, что есть файлы и без расширений, поэтому *.* не подойдет

а вообще погугли за *.bat файлы — у тебя именно тот момент, когда тебе пригодится работа в консоли, хе-хе.

Именно тот момент, когда не пригодится =\ Ты предложил пока самое сложное решение и написал, что оно не работает.

copy и move молча переписывают дубликаты, xcopy и robocopy не дают их переименовать, xxсopy умеет всё необходимое (переименование, слияние подпапок, проверка, логирование), но его нужно скачивать, xxxcopy (.com) давно закрылся.

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

Команда cp: правильное копирование папок с файлами в *nix

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

Допустим нам нужно скопировать всё из папки /source в папку /target.

Первое, что приходит на ум это:

Сразу исправим эту команду на:

Ключ -a добавит копирование всех аттрибутов, прав и добавит рекурсию. Когда не требуется точное воспроизведение прав достаточно ключа -r .

После копирования мы обнаружим, что скопировались не все файлы — были проигнорированы файлы начинающиеся с точки типа:

.profile
.local
.mc
и тому подобные.

Почему же так произошло?

Потому что wildcards обрабатывает shell ( bash в типовом случае). По умолчанию bash проигнорирует все файлы начинающиеся с точек, так как трактует их как скрытые. Чтобы избежать такого поведения нам придётся изменить поведение bash с помощью команды:

Чтобы это изменение поведения сохранилось после перезагрузки, можно сделать файл wildcard.sh c этой командой в папке /etc/profile.d (возможно в вашем дистрибутиве иная папка).

А если в директории-источнике нет файлов, то shell не сможет ничего подставить вместо звёздочки, и также копирование завершится с ошибкой. Против подобной ситуации есть опции failglob и nullglob . Нам потребуется выставить failglob , которая не даст команде выполниться. nullglob не подойдёт, так как она строку с wildcards не нашедшими совпадения преобразует в пустую строку (нулевой длины), что для cp вызовет ошибку.

Однако, если в папке тысячи файлов и больше, то от подхода с использованием wildcards стоит отказаться вовсе. Дело в том, что bash разворачивает wildcards в очень длинную командную строку наподобие:

На длину командной строки есть ограничение, которое мы можем узнать используя команду:

Получим максимальную длину командной строки в байтах:

Получим что-то типа:

Итак, давайте будем обходиться вовсе без wildcards.

Давайте просто напишем

И тут мы столкнёмся с неоднозначностью поведения cp . Если папки /target не существует, то мы получим то, что нам нужно.

Однако, если папка target существует, то файлы будут скопированы в папку /target/source.

Не всегда мы можем удалить заранее папку /target, так как в ней могут быть нужные нам файлы и наша цель, допустим, дополнить файлы в /target файлами из /source.

Если бы папки источника и приёмника назывались одинаково, например, мы копировали бы из /source в /home/source, то можно было бы использовать команду:

И после копирования файлы в /home/source оказались бы дополненными файлами из /source.

Чтобы обойти это вредное ограничение мы используем неочевидное решение:

Те кто хорошо знаком с DOS и Linux уже всё поняли: внутри каждой папки есть 2 невидимые папки «.» и «..», являющиеся псевдопапками-ссылками на текущую и вышестоящие директории.

  • При копировании cp проверяет существование и пытается создать /target/.
  • Такая директория существует и это есть /target
  • Файлы из /source скопированы в /target корректно.

Поведение этой команды однозначно. Всё отработает без ошибок вне зависимости от того миллион у вас файлов или их нет вовсе.

Выводы

Если нужно скопировать все файлы из одной папки в другую, не используем wildcards, вместо них лучше использовать cp в сочетании с точкой в конце папки-источника. Это скопирует все файлы, включая скрытые и не завалится при миллионах файлов или полном отсутствии файлов.

Послесловие

vmspike предложил аналогичный по результату вариант команды:

ВНИМАНИЕ: регистр буквы T имеет значение. Если перепутать, то получите полную белиберду: направление копирования поменяется.
Благодарности:

Copy-Item копирование файлов и папок из PowerShell

date13.05.2020
userinsci
directoryPowerShell
commentsкомментариев 9

PowerShell командлет Copy-Item используется для копирования файлов между локальными, сетевыми каталогами или между компьютерами по сети через WinRM. Командлет Copy-Item предоставляет большое количество опций, которые можно использовать в разных сценариях копирования файлов и каталогов (по своим возможностям этот командлет почти не уступает утилите robocopy). Например:

  • перезапись файлов (override)
  • фильтрация по имени/шаблону
  • исключение по имени/шаблону
  • Verbose режим
  • Копирование файлов с/на удаленные компьютеры

Начнем с простых примеров использования Copy-Item и будем переходить к более сложным.

Копирование файлов и каталогов

Чтобы скопировать один файл 1.txt из каталога C:\SourceFolder\ в F:\DestFolder\, выполните:

Copy-Item -Path «C:\SourceFolder\1.txt» -Destination «F:\DestFolder\1.txt»

Можно использовать сокращенный синтаксис командлета, пропустив указание параметров Path и Destination:

cpi «C:\SourceFolder\1.txt» «F:\DestFolder\1.txt»

Теперь скопируем каталог C:\SourceFolder\folder в F:\DestFolder\folder. В папке folder находится файл 1.txt. Обратите внимание что без ключа –Recurse, папка folder копируется без содержимого:

Copy-Item -Path «C:\SourceFolder\folder» -Destination «F:\DestFolder\folder» -Recurse

С помощью Copy-Item также можно просто объединить файлы из несколько директорий в одну (слияние директории), для этого нужно перечислить директории в ключе –Path:

Copy-Item -Path «C:\SourceFolder\*», «C:\SourceFolder2\*», «C:\SourceFolder3\*» -Destination «F:\DestFolder\»

Копирование с заменой и копирование с заменой read-only файлов

Copy-Item по умолчанию при копировании заменяет файлы в целевом каталоге. Никаких дополнительных параметров указывать не нужно. При копировании каталога, если нужно заменить каталог в целевой папке, нужно использовать ключ –Force, иначе будет ошибка “Элемент folder с указанным именем уже существует — DirectoryExists”.

copy-item DirectoryExists

Для перезаписи файла с атрибутом read-only, нужно использовать ключ -Force. Если его не использовать, вы получите ошибку “отказано в доступе по пути… CopyFileInfoItemUnauthorizedAccessError”.

copy-item CopyFileInfoItemUnauthorizedAccessError

Чтобы скопировать файл с перезаписью файла с read-only атрибутом используйте параметр Force.

Copy-Item -Path «C:\SourceFolder\1.txt» -Destination «F:\DestFolder\1.txt» -Force

Чтобы Copy-Item скопировал файлы из одной папки в другую без замены существующих файлов, можно использовать этот простой скрипт

Copy-Item (Join-Path «C:\SourceFolder\» «*») «F:\DestFolder\» -Exclude (Get-ChildItem «F:\DestFolder\») -Recurse

Этот скрипт скопирует все файлы и папки из C:\SourceFolder в F:\DestFolder без замены файлов уже существующих в F:\DestFolder

Копирование с фильтрацией по шаблону

С помощью Copy-Item можно скопировать файлы/директории выбранные с помощью wildcard символа * или с помощью символа ?. Также поддерживаются некоторые регулярные выражения

  • * — обозначает любое количество любых символов
  • ? – обозначает 1 любой символ
  • [a-z], [0-9] – символы между a-z и цифры между 0 и 9

Для примера возьмём такую структуру файлов:

source

Выполним копирование командой:

Copy-Item -Path «C:\SourceFolder\fol*» -Destination «F:\DestFolder\»

Результат в F:\DestFolder\

copy-item replace

Теперь чистим папку назначения и выполняем:

Copy-Item -Path «C:\SourceFolder\folder[0-3]» -Destination «F:\DestFolder\»

result

Папка без цифры в окончании не скопировалась, потому что folder[0-3] подразумевает что после folder будет как минимум еще 1 символ между 0 и 3

Исключение файлов при копировании

С помощью ключа –Exclude можно исключить файлы при копировании. Например, следующай команда скопирует все файлы кроме файлов с расширением txt.

Copy-Item -Path «C:\SourceFolder\*» -Destination «F:\DestFolder\» -Recurse -Force -Exclude «*.txt»

Аналогичным же образом можно применить ключ –Include, например

Copy-Item -Path «C:\SourceFolder\*» -Destination «F:\DestFolder\» -Recurse -Force -Include «*.txt»

Скопирует только txt файлы. Хотя для простоты гораздо удобнее использовать при копировании вид -Path «C:\SourceFolder\*.txt» .

Копирование файлов на удаленный компьютер по сети

Copy-File может копировать не только по SMB протоколу, но и через WinRM (WSMan).

Создайте новую сессию с компьютером testnode1 и выполните копирование в её контексте:

$session = New-PSSession -ComputerName testnode1
Copy-Item -Path «C:\SourceFolder\*» -ToSession $session -Destination «C:\SourceFolder\» -Recurse -Force

Эта команда скопирует файлы с локального компьютера из директории C:\SourceFolder на компьютер testnode1 в C:\SourceFolder\.

Test-WSMan -ComputerName testnode1

Test-WSMan

Если WSMan не настроен, вы можете выполнить его быструю конфигурацию. Для этого откройте командную строку с правами администратора и выполните winrm quickconfig

winrm quickconfig

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

Copy-Item -Path «C:\SourceFolder\*» -Destination «\\testnode1\C$\copy_tutorial\»

Можно скопировать файл с удаленного компьютера. Принцип такой же, как и при копировании файлов на удаленный компьютер, за исключением параметра –ToSession, вместо него нужно использовать –FromSession:

$session = New-PSSession -ComputerName testnode1
Copy-Item -FromSession $session -Path «C:\SourceFolder\*» -Destination «F:\DestFolder\» -Recurse -Force

Эта команда скопирует содержимое папки C:\SourceFolder\ с компьютера testnode1 на локальный компьютер в директорию F:\DestFolder

Ключ PassThru

Командлет Copy-Item (как и многие другие командлеты PowerShell) не возвращает результатов в консоль. Параметр PassThru применяется скриптах, или для лог-файлов, когда нужно получить список скопированных файлов и работать с ним дальше. Рассмотрим пример

$items = Copy-Item -Path «C:\SourceFolder\*» –Destination «\\testnode1\C$\copy_tutorial\» -PassThru

Переменная $items будет содержать список скопированных файлов, с которым вы можете работать дальше.Это значит что вы можете напрямую работать с этими файлами. Например выполнив команду Remove-Item $items[0] , вы удалите директорию folder.

copy-item passthru

Ключ Verbose

При использовании ключа -Verbose вы получите подробный лог операций копирования. Например, вывод команды

Copy-Item -Path «C:\SourceFolder\*.txt» -Destination «F:\DestFolder\» -Recurse -Force -Verbose

copy-item verbose лог

Несколько полезных скриптов с Copy-Item

Скопировать только файлы:

Get-ChildItem «C:\SourceFolder» -File -Recurse | Copy-Item -Destination «F:\DestFolder»

Скопировать структуру папок, без файлов:

$path = Get-ChildItem «C:\SourceFolder» -Recurse | ?<$_.PsIsContainer -eq $true>
$dest = «F:\DestFolder\»
$parent = $path[0].Parent.Name
$path | foreach <
$_.FullName -match «$parent.+»
New-Item -ItemType directory ($dest + $Matches[0])
>

Copy-Item очень простой и удобный в использовании командлет PowerShell для выполнения операций копирования и перемещения файлов. В сочетании с другими инструментами PowerShell, Copy-Item также является мощным инструментом для написания скриптов.

Предыдущая статьяПредыдущая статья Следующая статья Следующая статья

Как скопировать сразу все файлы из множества подпапок

Всем доброго времени суток и всяческих прочих разностей.

Небольшая заметка в блог, которая может немного упростить кому-либо жизнь в определенной ситуации, а точнее говоря спасти бесценное времени. Речь идет о ситуации, когда у Вас есть огромное количество подпапок в каждой из которых лежат файлы и все их надо скопировать в одну.

folder

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

Рассказываю как сделать это быстро и просто.

Чтобы Вы поняли о чем идет речь, есть вот такая вот каша из более чем тысячи папок в которых, собственно, тысячи файлов:

множество папок с множеством файлов

Нужно получить на выходе такую вот кашу из всех файлов, но в одной папке:

sdfs dsfd fsd

Можно сделать это консолью, но можно и поступить попроще. Скачиваем Total Commander , запускаем, открываем папку в которой лежат подпапки с папками, т.е верхнюю в структуре:

fds fds sdfsdf

Нажимаем на клавиатуре Ctrl+B , чтобы отобразить все файлы во всех папках и подпапках, одним списком, т.е без папок, т.е содержимое:

sdf sdfsfd sdf

Используя, скажем, мышь или клавишу F5 (копирование) или клавишу F6 (перемещение) копируем в нужную нам папку.

На сим, собственно, всё, такая вот кратенькая заметка.
Авось кому-нибудь пригодится 😉

Белов Андрей (Sonikelf) alt=»Sonikelf» /> alt=»Sonikelf» />Заметки Сис.Админа [Sonikelf’s Project’s] Космодамианская наб., 32-34 Россия, Москва (916) 174-8226

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *