批处理文件以循环遍历文件夹并将文件夹和内容复制到具有相同文件夹名称的目录

Posted

技术标签:

【中文标题】批处理文件以循环遍历文件夹并将文件夹和内容复制到具有相同文件夹名称的目录【英文标题】:Batch File to Loop Through Folders and Copy Folder & Contents to Directory with Same Folder Name 【发布时间】:2014-12-14 17:06:51 【问题描述】:

每个月,公司都会将不同数量的文件转储(保存)到共享网络驱动器上不同数量的文件夹中。这些文件包含 .xlsx 或 .pdf 文件格式的信息,文件夹代表不同的项目。文件夹名称仅包含项目编号(即 12345、15241-0001、16755-0004 等...)。通常是五位数字或五位数字后跟一个连字符,然后是一个四位数字。

我希望能够创建一个批处理文件,该批处理文件可以运行以循环浏览公司转储到共享网络共享驱动器的文件夹,然后将项目文件夹和内容(文件)复制到另一个共享网络驱动器包含我部门操作使用的相应项目文件夹。操作共享网络驱动器上的项目文件夹名称包含项目编号、空格、连字符、另一个空格,然后是项目名称(即 12345 - Project 1、15241-0001 - Project 22、16755-0004 - Project 12、等等……)

更新... Magoo,当我从您的帖子中学习时,您一直很准确并且提供了很大的帮助。我没有考虑到运营端的子项目都在主项目文件夹中:

u:\destdir\2015\15241\15241-0001 - Project 06 u:\destdir\2015\15241\15241-0001 - Projekt 60 u:\destdir\2016\16755\16755-0004 - Project 14

因此脚本不会将文件复制到子项目,因为脚本认为目标不存在。是否可以获取项目的前五个字符并插入到xcopy命令的目标目录中?

【问题讨论】:

【参考方案1】:
@ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir\t w o"
SET "destdir=U:\destdir"
FOR /f "delims=" %%a IN (
 'dir /b /ad "%sourcedir%\*" '
 ) DO (
 FOR /f "delims=" %%b IN (
  'dir /b /ad "%destdir%\%%a*" '
  ) DO (
  ECHO(XCOPY /s "%sourcedir%\%%a\*" "%destdir%\%%b\"
)
)

GOTO :EOF

您需要更改sourcedirdestdir 的设置以适应您的情况。

所需的 XCOPY 命令仅用于测试目的ECHOed。 验证命令正确后,将ECHO(XCOPY 更改为XCOPY 以实际复制文件。


编辑:根据另外一半的信息进行修订。

假设目标结构是...\2012\12???(-?????) - waffle 那么

@ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir\t w o"
SET "destdir=U:\destdir"
FOR /f "delims=" %%a IN (
 'dir /b /ad "%sourcedir%\*" '
 ) DO CALL :process "%%a"

GOTO :EOF

:process
SET "year=%~1"
SET /a year=20%year:~0,2%
SET "copied="
FOR /f "delims=" %%b IN (
 'dir /b /ad "%destdir%\%year%\%~1*" 2^>nul'
 ) DO IF DEFINED copied (ECHO %1 NOT copied to duplicate destination "%destdir%\%year%\%%b\"
 ) ELSE (
  SET "copied=%destdir%\%%b\"
  ECHO(                    XCOPY /s "%sourcedir%\%~1\*" "%destdir%\%year%\%%b\"
 )
)
IF DEFINED copied (ECHO %1 WAS copied to destination "%copied%"
) else (ECHO %1 WAS NOT copied - no destination found)
GOTO :EOF

您需要更改sourcedirdestdir 的设置以适应您的情况。

测试结果:

目标目录结构

u:\destdir\2012
u:\destdir\2015
u:\destdir\2016
u:\destdir\2012\12345 - Project 98
u:\destdir\2015\15241-0001 - Project 06
u:\destdir\2015\15241-0001 - Projekt 60
u:\destdir\2016\16755-0004 - Project 14

过程输出:

                    XCOPY /s "U:\sourcedir\t w o\12345\*" "U:\destdir\2012\12345 - Project 98\"
"12345" WAS copied to destination "U:\destdir\12345 - Project 98\"
                    XCOPY /s "U:\sourcedir\t w o\15241-0001\*" "U:\destdir\2015\15241-0001 - Project 06\"
"15241-0001" NOT copied to duplicate destination "U:\destdir\2015\15241-0001 - Projekt 60\"
"15241-0001" WAS copied to destination "U:\destdir\15241-0001 - Project 06\"
                    XCOPY /s "U:\sourcedir\t w o\16755-0004\*" "U:\destdir\2016\16755-0004 - Project 14\"
"16755-0004" WAS copied to destination "U:\destdir\16755-0004 - Project 14\"
"13234-1234" WAS NOT copied - no destination found

请注意,xcopy 行缩进以便于分隔。

连字符对我有用!


修改以处理排除列表 - 假设排除列表将比包含列表短(2 行更改 - 添加排除列表 set 并处理该列表。

@ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir\t w o"
SET "destdir=U:\destdir"
SET "excluding=16755-0004"
FOR /f "delims=" %%a IN (
 'dir /b /ad "%sourcedir%\*" '
 ) DO CALL :process "%%a"

GOTO :EOF

:process
FOR %%x IN (%excluding% dummy) DO IF "%~1"=="%%x" ECHO %1 WAS NOT copied - excluded&GOTO :EOF 
SET "year=%~1"
SET /a year=20%year:~0,2%
SET "copied="
FOR /f "delims=" %%b IN (
 'dir /b /ad "%destdir%\%year%\%~1*" 2^>nul'
 ) DO IF DEFINED copied (ECHO %1 NOT copied to duplicate destination "%destdir%\%year%\%%b\"
 ) ELSE (
  SET "copied=%destdir%\%%b\"
  ECHO(                    XCOPY /s "%sourcedir%\%~1\*" "%destdir%\%year%\%%b\"
 )
)
IF DEFINED copied (ECHO %1 WAS copied to destination "%copied%"
) else (ECHO %1 WAS NOT copied - no destination found)
GOTO :EOF

注意包含dummy 以确保for %%x 循环中的列表不为空。


对于下一个需求(目录中的“项目”级别),再添加一行 - 但为了便于测试,我取消了 excluding 行。

@ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir\t w o"
SET "destdir=U:\destdir"
REM SET "excluding=16755-0004"
FOR /f "delims=" %%a IN (
 'dir /b /ad "%sourcedir%\*" '
 ) DO CALL :process "%%a"

GOTO :EOF

:process
FOR %%x IN (%excluding% dummy) DO IF "%~1"=="%%x" ECHO %1 WAS NOT copied - excluded&GOTO :EOF 
SET "year=%~1"
SET /a year=20%year:~0,2%
FOR /f "tokens=1,2delims=-" %%x IN (%1) DO IF NOT "%%y"=="" SET "year=%year%\%%x"
SET "copied="
FOR /f "delims=" %%b IN (
 'dir /b /ad "%destdir%\%year%\%~1*" 2^>nul'
 ) DO IF DEFINED copied (ECHO %1 NOT copied to duplicate destination "%destdir%\%year%\%%b\"
 ) ELSE (
  SET "copied=%destdir%\%%b\"
  ECHO(                    XCOPY /s "%sourcedir%\%~1\*" "%destdir%\%year%\%%b\"
 )
)
IF DEFINED copied (ECHO %1 WAS copied to destination "%copied%"
) else (ECHO %1 WAS NOT copied - no destination found)
GOTO :EOF

year 现在不再只包含年份,如果提供的文件名包含子项目,则可能是下一个较低的目录级别(项目)。

【讨论】:

我在原始帖子中遗漏了一些内容。好的,按预期工作,但有一个障碍......如果有多个目标文件夹怎么办。目标文件夹名称代表项目开始的年份。我收到“找不到文件”,因为目标变量设置为“2014”。目标变量应代表项目文件夹名称的前两位,即 12503-0001 将保存到“2012”文件夹。所有公司转储文件夹都位于共享网络驱动器上的一个位置。 我无法编辑评论,但脚本也不会拾取包含连字符“-”的文件夹。 该解决方案效果很好。感谢 Magoo 的帮助。您将进行哪些修改以限制仅复制某些项目文件夹中的数据?排除列表还是包含列表? 更新... Magoo,您一直在现场并提供了很大的帮助,因为我正在从您的帖子中学习。我没有考虑到运营端的子项目都在主项目文件夹中:u:\destdir\2015\15241\15241-0001 - Project 06 u:\destdir\2015\15241\15241- 0001 - Projekt 60 u:\destdir\2016\16755\16755-0004 - 项目 14 因此脚本不会将文件复制到子项目,因为脚本认为目标不存在。是否可以获取项目的前五个字符并插入到xcopy命令的目标目录中?

以上是关于批处理文件以循环遍历文件夹并将文件夹和内容复制到具有相同文件夹名称的目录的主要内容,如果未能解决你的问题,请参考以下文章

VBA:循环遍历各种Excel文件并将列复制到主文件中[关闭]

批处理文件一次检索一行,然后循环遍历文件目录以查找每行的匹配项

循环遍历目录一层,并在该目录中以目录名作为参数执行脚本

我正在尝试创建一个在循环遍历文本文件时使用变量值的类

遍历xml文件并将内容存储在Textfield c#中

循环遍历子目录批处理文件中的文件