Board logo

标题: [文件操作] 批处理如何将多个文件夹里相同名称的子文件夹里的内容合并在一起 [打印本页]

作者: 97867564    时间: 2016-11-22 12:00     标题: 批处理如何将多个文件夹里相同名称的子文件夹里的内容合并在一起

本帖最后由 pcl_test 于 2016-11-22 15:41 编辑

具体内容:有one,two,three等多个文件夹,在这些文件夹下都有相同的a,b,c,d四个字文件夹。现在需要大神帮忙解决的在one,two,three同等级别下把相同名字的子文件夹合并起来,把所有a的字文件夹合并到a文件夹,b的合并到b文件夹中,
作者: CommandBatCmd    时间: 2016-11-22 15:34

回复 1# 97867564


  
  1. @echo off
  2. :: 如果源时间比目标时间新,改写现存目标文件。
  3. set "new=MergerDir"
  4. if not exist ".\%new%\" md ".\%new%"
  5. for %%i in (a b c d) do (
  6.     for /f %%j in ('dir /b /a:d') do (
  7.         if /i not "%%~j"=="%new%" (
  8.             if exist "%~dp0%%~j\%%i\" (
  9.                 xcopy /Y /D /E /Q /K "%~dp0%%~j\%%i\*" "%~dp0%new%\%%i\*" >nul
  10. ))))
  11. pause
复制代码

作者: 97867564    时间: 2016-11-24 11:01

回复 2# CommandBatCmd


    大神,或许我没有表达清楚,我就是复制过去的时候,不要覆盖原文件夹内的文件,同时也保留原文件和复制过去的文件,BAT中是否有这样的参数。当我手动复制过去的时候可以实现,不过现在数据很多,单纯的手动效率太低, 我也网上找了不少办法,都不行,希望大神可以再帮助下。
作者: CommandBatCmd    时间: 2016-11-24 21:01

回复 3# 97867564


   
    xcopy没有自动跳过目标已存在的参数,但可以给xcopy传递足够多的n来实现跳过。
  1. xcopy /Y /D /E /Q /R "%~dp0%%~j\%%i\*" "%~dp0%new%\%%i\*" >nul
复制代码
改为
  1. (for /L %%l in (1,1,9999) do @set /p=n<nul)|xcopy /E /Q "%~dp0%%~j\%%i\*" "%~dp0%new%\%%i\*"
复制代码
如果9999少于来源目录中的总文件数,可再加9 。或者把9999做成变量,交给dir去实时获取。
作者: pcl_test    时间: 2016-11-24 21:29

每个文件夹里只有a、b、c、d四个子文件夹么?
a、b、c、d四个子文件夹里只有文件没有文件夹么?
作者: 97867564    时间: 2016-11-25 17:44

回复 5# pcl_test


    是的,还有些名字一样的文件。
作者: CommandBatCmd    时间: 2016-11-25 23:57

回复 6# 97867564


    试试下面的,看是否达到目的
  1. @echo off
  2. :: 第一次启动,所有的重复文件,以重命名的形式合并;
  3. :: 第二次启动,第一次没有进行重复的,可能以重命名的形式再重复一次,不重复的继续合并;
  4. :: 再重复启动,没有新的文件名称,跳过全部重复文件,如有则继续合并。
  5. set "new=MergerDir"
  6. if not exist ".\%new%\" md ".\%new%"
  7. for %%I in (a b c d) do (
  8.     for /f "delims=" %%J in ('dir /b /a:d') do (
  9.         if /i not "%%~J"=="%new%" (
  10.             if exist "%~dp0%%~J\%%~I\" (
  11.                 if not exist "%~dp0%new%\%%~I\" (md "%~dp0%new%\%%~I")
  12.                 for /f "delims=" %%K in ('dir /b /a:-d "%~dp0%%~J\%%~I" 2^>nul') do (
  13.                     set/a n+=1
  14.                     if not exist "%~dp0%new%\%%~I\%%~nxK" (
  15.                         copy "%~dp0%%~J\%%~I\%%~nxK" "%~dp0%new%\%%~I\%%~nxK"
  16.                     ) else (
  17.                         setlocal enabledelayedexpansion
  18.                             if not exist "%~dp0%new%\%%~I\%%~nK_重复[!n!]%%~xK" (
  19.                                 copy "%~dp0%%~J\%%~I\%%~nxK" "%~dp0%new%\%%~I\%%~nK_重复[!n!]%%~xK"
  20.                             ) else (@rem 以下测试用,看起来烦,用“@rem”屏障掉“echo”,或把“此条else”语句删除。
  21.                                 echo;"%~dp0%new%\%%~I\%%~nK_重复[!n!]%%~xK"
  22.                                 echo;跳过以上重复的重复。&echo;
  23.                             )
  24.                         endlocal
  25.                     )
  26.                 )
  27.                 set n=0
  28.             )
  29.         )
  30.     )
  31. )
  32. pause
复制代码

作者: /zhqsystem/zhq    时间: 2016-11-26 02:17

本帖最后由 /zhqsystem/zhq 于 2016-11-26 02:22 编辑
  1. @echo off&setlocal enabledelayedexpansion
  2. for /f "delims=" %%i in ('"dir/ad/s/b/l/og "%~dp0*.*""')do (
  3. for /f "delims=" %%j in ("%%~fi\..")do (
  4.   for %%n in (a,b,c,d)do (
  5.    if "%%~fi"=="%%~fj\%%n" (
  6.     if exist "%%~dpj合并数据\%%~n\" md "%%~dpj合并数据\%%~n\"
  7.      if not exist "%%~dpj合并数据\%%~n\自动重命名%%~nxj_%%~nxi" (
  8.       for /f "delims=" %%c in ('dir/a-d/b "%%~fi\*.*"')do (
  9.        echo,f|xcopy "%%~fi\%%~nxc" "%%~dpj合并数据\%%~n\自动重命名%%~nxj_%%~nxi_%%~nxc"
  10.        (echo,"%%~dpj合并数据\%%~n\自动重命名%%~nxj_%%~nxi_%%~nxc" "%%~fi\%%~nxc")>>"%~dp0数据记录用于返回原来结构.txt"
  11.       )
  12.      )
  13.     )
  14.    )
  15.   )
  16. )
  17. )
  18. pause
复制代码

作者: 97867564    时间: 2016-11-28 14:46

那么多大神来帮助,谢谢各位了。
作者: CommandBatCmd    时间: 2016-11-28 15:02

回复 9# 97867564


    要是能够解决了你的问题就好!?
作者: 97867564    时间: 2016-11-28 15:51

回复 7# CommandBatCmd


     for /f "delims=" %%J in ('dir /b /a:d')
大神这段代码后面()这里面是什么意思?
作者: CommandBatCmd    时间: 2016-11-28 16:26

回复 11# 97867564


08. @rem 列出当前目录中的多个文件夹的名称。
09. @rem 排除合并后的保存文件夹
10. @rem 如果当前目录中的某个文件夹下有子文件夹a b c d之一,则继续。
11. @rem 如果保存文件夹中没有a b c d之一,则创建。
12. @rem 列出找到的a b c d之一下的所有文件。
13. @rem 计数,为a b c d之一下的所有重复文件生成重命名序号。
14. @rem 如果来源a b c d之一下文件在对应的保存文件夹不存在,则直接拷贝过来。
15. @rem 来源>目标,直接拷贝。
16. @rem 如果来源在目标中存在,则执行下面的。
17. @rem 临时开启变量延迟,此句也可以放到文件头部,然后删除后面的“endlocal”
18. @rem 如果重复文件以前没有重复过,直接以重命名方式拷贝过来。
19. @rem 来源>目标,直接以重命名方式拷贝。
20. @rem 以下测试用,看起来烦,用“@rem”屏障掉“echo”,或把“此条else”语句删除。
28. @rem 如果来源a b c d之一中的所有文件处理完毕,重置计数为0
作者: 97867564    时间: 2016-11-28 16:29

回复 10# CommandBatCmd


    大神,这个能用,就是速度慢,这个无所谓了,BAT本人还在学习中,这次多亏您帮忙了,
作者: CommandBatCmd    时间: 2016-11-28 17:04

回复 13# 97867564


    FOR 嵌套太深对速度的影响是肯定的,如果对比大量拷贝文件的时间,可以忽略不计。
如果FOR 不要嵌套,你可以搞个临时文件,三步法完成任务:
1.收集文件信息,2.处理收集信息,3.一次性拷贝结果;
这样代码的处理手时间应该在几秒之内,其余时间拷贝。
作者: 97867564    时间: 2016-11-29 14:28

回复 14# CommandBatCmd


    大神,现在用下来遇到个问题, 文件夹归档的数量不对。应该最起码有上百个文件夹,现在运行下来只有九十几个,能帮忙再看看吗?
作者: CommandBatCmd    时间: 2016-11-29 21:39

回复 15# 97867564


    你不是回答过5楼

每个文件夹里只有a、b、c、d四个子文件夹么?
a、b、c、d四个子文件夹里只有文件没有文件夹么?

是的,还有些名字一样的文件。

这个代码的功能就是:
1. 查找当前目录下的所有文件夹(不包括子文件夹),并排除保存文件夹;
2. 把找到的所有文件夹下的每一个a、b、c、d四个子文件夹之下的所有文件,
   拷贝到保存文件夹中对应a、b、c、d文件夹之内。
3. 如第一次拷贝时,有重复就重命名,再次运行,跳过全部重复的文件,有新名称则继续拷贝。

而现在却是:
最起码有上百个文件夹,运行下来只有九十几个,文件夹归档的数量不对。

代码除以上所说,别的它就干不了啦!
这是什么情况?




欢迎光临 批处理之家 (http://www.bathome.net/) Powered by Discuz! 7.2