Копировать файлы из одной папки в несколько других папок, откуда эти файлы изначально взялись. Windows

Копировать файлы из одной папки в несколько других папок, откуда эти файлы изначально взялись. Windows

Привет, у меня следующая проблема.

Предположим, у вас есть некая структура папок Windows с различными файлами (все файлы имеют разные имена, но могут иметь одинаковое расширение):

dirA
  subDirA
    file1.png
    file2.dds
  file3.jpeg
dirB
  subDirB
    subSubDirB
      file4.tiff
    some_txt.txt
  test.cfg
final.docx

А теперь вы рекурсивно копируете все файлы в какой-то другой каталог:

file1.png
file2.dds
file3.jpeg
file4.tiff
some_txt.txt
test.cfg
final.docx

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

Есть ли какой-то простой способ сделать это или мне лучше написать специальную программу/скрипт для этого?

решение1

Я обычно предпочитаю пакетное решение для чего-то вроде этого:

@echo off

set "orig=C:\Original\Directory"
set "dir=C:\Some\Directory"

for /r "%orig%" %%A in (*) do (
    if exist "%dir%\%%~nxA" copy /y "%dir%\%%~nxA" "%%A"
)

Переменная origбудет папкой верхнего уровня, по которой вы хотите рекурсивно пройтись (т. е. dirAили dirBиз вашего блока примера - или, если они имеют общую папку, вы можете идти так высоко, как захотите, при условии, что вы уверены, что нет повторяющихся имен). Переменная dirбудет папкой, в которую вы ранее скопировали все файлы.

for /rциклы черезвсефайлы, находящиеся в корне каталога (то есть origи все его подпапки); для каждой итерации он устанавливает полный путь и расширение файла как %%A, затем внутри цикла мы смотрим, %%~nxAсуществует ли (файл, сокращенный до его имени и расширения) в нашем dirместоположении; если он существует, мы копируем этот файл из dirсебя в origместоположении. Вот и все. Если вы хотите сгенерировать файл журнала для проверки, я обычно рекомендую использовать robocopy и заставить его выводить все из цикла в текстовый файл, который будет выглядеть так:

@echo off

set "orig=C:\Original\Directory"
set "dir=C:\Some\Directory"

setlocal enabledelayedexpansion
for /r "%orig%" %%A in (*) do (
    set "path=%%~dpA"
    if exist "%dir%\%%~nxA" robocopy "%dir%" "!path:~0,-1!" "%%~nxA"
)>>"%dir%\Return Files.txt"

Единственное сложное отличие заключается в необходимости включить отложенное расширение, чтобы можно было обрезать конечный фрагмент \из %%~dpA.

решение2

То, что вы хотите сделать, невозможно: Файлы в новом месте больше не имеют информации о том, откуда они взялись. Это подразумевает, что у скрипта нет возможности узнать, куда он должен поместить каждый файл.

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

решение3

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

forfiles /P X:\originals_folder /S /C "cmd /c copy Y:\copies_folder\@file @path\@file /Y"

решение4

Решение PowerShell, использующее хеш-таблицу для поиска путей:

$originals = 'c:\originals'
$copies    = 'c:\copies'
$hash = @{}
gci $originals -recurse | %{
   $hash[$_.name] = $_.Fullname
}
gci $copies | %{copy-item $_ $hash[$_.Name] -force

Связанный контент