
Привет, у меня следующая проблема.
Предположим, у вас есть некая структура папок 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