![将文件从一个文件夹复制到这些文件原来的多个其他文件夹。Windows](https://linux22.com/image/1596293/%E5%B0%86%E6%96%87%E4%BB%B6%E4%BB%8E%E4%B8%80%E4%B8%AA%E6%96%87%E4%BB%B6%E5%A4%B9%E5%A4%8D%E5%88%B6%E5%88%B0%E8%BF%99%E4%BA%9B%E6%96%87%E4%BB%B6%E5%8E%9F%E6%9D%A5%E7%9A%84%E5%A4%9A%E4%B8%AA%E5%85%B6%E4%BB%96%E6%96%87%E4%BB%B6%E5%A4%B9%E3%80%82Windows.png)
你好,我有以下问题
假设您有一些包含不同文件的 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