zoukankan      html  css  js  c++  java
  • dos下遍历目录和文件的代码(主要利用for命令)(转)

    ===== 文件夹结构 ============================================= 
    D: est 
    ---A Folder 1 
    |-----A file 1.txt 

    |-----A file 2.txt 
    |-----A file 3.txt 
    ---B Folder 2 
    |-----B file 1.txt 
    |-----B file 2.txt 
    |-----B file 3.txt 
    |---B Folder 3 
    |-----B sub file 1.txt 
    |-----B sub file 2.txt 
    |-----B sub file 3.txt 
     

    复制代码代码如下:

    1 @echo off 
    2 set work_path=D:test 
    3 D: 
    4 cd %work_path% 
    5 for /R %%s in (.,*) do ( 
    6 echo %%s 
    7 ) 
    8 pause 


    结果 
    D: est. 
    D: estA Folder 1. 
    D: estA Folder 1A file 1.txt 
    D: estA Folder 1A file 2.txt 
    D: estA Folder 1A file 3.txt 
    D: estB Folder 2. 
    D: estB Folder 2B file 1.txt 
    D: estB Folder 2B file 2.txt 
    D: estB Folder 2B file 3.txt 
    D: estB Folder 2B Folder 3. 
    D: estB Folder 2B Folder 3B sub file 1.txt 
    D: estB Folder 2B Folder 3B sub file 2.txt 
    D: estB Folder 2B Folder 3B sub file 3.txt 

    复制代码代码如下:

    1 @echo off 
    2 set work_path=D:test 
    3 D: 
    4 cd %work_path% 
    5 for /R %%s in (.) do ( 
    6 echo %%s 
    7 ) 
    8 pause 


    结果 
    D: est. 
    D: estA Folder 1. 
    D: estA Folder 1A file 1.txt 
    D: estA Folder 1A file 2.txt 
    D: estA Folder 1A file 3.txt 
    D: estB Folder 2. 
    D: estB Folder 2B file 1.txt 
    D: estB Folder 2B file 2.txt 
    D: estB Folder 2B file 3.txt 
    D: estB Folder 2B Folder 3. 
    D: estB Folder 2B Folder 3B sub file 1.txt 
    D: estB Folder 2B Folder 3B sub file 2.txt 
    D: estB Folder 2B Folder 3B sub file 3.txt 

    那么 

    复制代码代码如下:

    1 for /R %%s in (.,*) do ( 
    2 echo %%s 
    3 ) 


    和 

    复制代码代码如下:

    1 for /R %%s in (.) do ( 
    2 echo %%s 
    3 ) 


    的区别是什么呢? 
    在有cd %work_path% 的时候,这两个命令执行的结果是一样的,就像我们上面举的例子。但是 

    1 for /R %%s in (.,*) do ( 
    2 echo %%s 
    3 ) 


    的批处理中没有cd %work_path% ,那么显示的将是这个批处理文件所在文件夹下面的遍历结果。 

    复制代码代码如下:

    1 @echo off 
    2 for /R "D:	est" %%s in (.) do ( 
    3 echo %%s 
    4 ) 
    5 pause 


    结果 
    D: est. 
    D: estA Folder 1. 
    D: estB Folder 2. 
    D: estB Folder 2B Folder 3. 

    复制代码代码如下:

    1 @echo off 
    2 for /R "D:	est" %%s in (.,*) do ( 
    3 echo %%s 
    4 ) 
    5 pause 


    结果 
    D: est. 
    D: estA Folder 1. 
    D: estA Folder 1A file 1.txt 
    D: estA Folder 1A file 2.txt 
    D: estA Folder 1A file 3.txt 
    D: estB Folder 2. 
    D: estB Folder 2B file 1.txt 
    D: estB Folder 2B file 2.txt 
    D: estB Folder 2B file 3.txt 
    D: estB Folder 2B Folder 3. 
    D: estB Folder 2B Folder 3B sub file 1.txt 
    D: estB Folder 2B Folder 3B sub file 2.txt 
    D: estB Folder 2B Folder 3B sub file 3.txt 

    这样的话看出来区别了吧。 

    再看一个================================= 

    复制代码代码如下:

    1 @echo off 
    2 for /R "D:	est" %%s in (*) do ( 
    3 echo %%s 
    4 ) 
    5 pause 


    结果 
    D: estA Folder 1A file 1.txt 
    D: estA Folder 1A file 2.txt 
    D: estA Folder 1A file 3.txt 
    D: estB Folder 2B file 1.txt 
    D: estB Folder 2B file 2.txt 
    D: estB Folder 2B file 3.txt 
    D: estB Folder 2B Folder 3B sub file 1.txt 
    D: estB Folder 2B Folder 3B sub file 2.txt 
    D: estB Folder 2B Folder 3B sub file 3.txt 
    就是只显示了文件
    VisitF.bat - 对指定路径指定文件进行遍历的程序 

    复制代码代码如下:

     1 :: VisitF.bat - 对指定路径指定文件进行遍历的程序 
     2 :: 第一参数为要遍历的文件(支持通配符),第二参数为要遍历的路径(缺省为C盘根) 
     3 @echo off 
     4 :main 
     5 if [%1]==[] if not exist goto end 
     6 :init 
     7 if exist if exist goto loop 
     8 set file=%1 
     9 set base=%2 
    10 if [%2]==[] set base=c: 
    11 dir %base%\%file% /s /a /b > 
    12 echo e 100 ''set file='' > 
    13 echo w >> 
    14 echo q >> 
    15 :loop 
    16 fc nul /n | find " 1:" > setfile.bat 
    17 if errorlevel 1 goto restore 
    18 debug setfile.bat nul 
    19 call setfile.bat 
    20 echo Visiting the file: %file% 
    21 :: User specified visit code replace this line 
    22 find "%file%" /v 
    23 copy > nul 
    24 goto loop 
    25 :restore 
    26 if exist del 
    27 if exist del 
    28 if exist del 
    29 if exist setfile.bat del setfile.bat 
    30 :end 



    VisitD.bat - 对指定路径指定目录进行遍历的程序 

    复制代码代码如下:

     1 :: VisitD.bat - 对指定路径指定目录进行遍历的程序 
     2 :: 第一参数为要遍历的目录(支持通配符),第二参数为要遍历的路径(缺省为C盘根) 
     3 @echo off 
     4 :main 
     5 if [%1]==[] if not exist goto end 
     6 :init 
     7 if exist if exist goto loop 
     8 set dir=%1 
     9 set base=%2 
    10 if [%2]==[] set base=c: 
    11 dir %base%\%dir% /s /ad /b > 
    12 echo e 100 'set dir=' > 
    13 echo w >> 
    14 echo q >> 
    15 :loop 
    16 fc nul /n | find " 1:" > setdir.bat 
    17 if errorlevel 1 goto restore 
    18 debug setdir.bat nul 
    19 call setdir.bat 
    20 echo Visiting the dir: %dir% 
    21 :: User specified visit code replace this line 
    22 find "%dir%" /v 
    23 copy > nul 
    24 goto loop 
    25 :restore 
    26 if exist del 
    27 if exist del 
    28 if exist del 
    29 if exist setdir.bat del setdir.bat 
    30 :end 


    VisitL.bat - 对指定文件列表中的文件进行遍历的程序 

    复制代码代码如下:

     1 :: VisitL.bat - 对指定文件列表中的文件进行遍历的程序 
     2 :: 参数为要遍历的文件列表 
     3 @echo off 
     4 :main 
     5 if [%1]==[] if not exist goto end 
     6 :init 
     7 set filelist=%1 
     8 if [%1]==[] set filelist= 
     9 if not exist %filelist% goto end 
    10 copy %filelist% > nul 
    11 if exist goto loop 
    12 echo e 100 'set file=' > 
    13 echo w >> 
    14 echo q >> 
    15 :loop 
    16 fc nul /n | find " 1:" > setfile.bat 
    17 if errorlevel 1 goto restore 
    18 debug setfile.bat nul 
    19 call setfile.bat 
    20 echo Visiting the file: %file% 
    21 :: User specified visit code replace this line 
    22 find "%file%" /v 
    23 copy > nul 
    24 goto loop 
    25 :restore 
    26 if exist del 
    27 if exist del 
    28 if exist del 
    29 if exist setfile.bat del setfile.bat 
    30 :end 



    VisitI.bat - 对指定路径指定DIR信息的文件进行遍历操作的的程序 

    复制代码代码如下:

    :: VisitI.bat - 对指定路径指定DIR信息的文件进行遍历操作的的程序 
    :: 第一参数为指定的DIR信息项,第二参数为要遍历的路径(缺省为当前路径) 
    :: 注意:DIR信息项可以是文件名,扩展名,日期,时间等DIR命令提供的目录信息项 
    :: 可以同时使用多项,但必须加一对引号,参数格式也须严格符合DIR的信息格式 
    @echo off 
    :main 
    if [%1]==[] goto end 
    :init 
    if exist if exist goto loop 
    set info=%1 
    set base=%2 
    if [%2]==[] set base=. 
    dir %base%. /s /a /b > 
    echo e 100 ''''set file='''' > 
    echo w >> 
    echo q >> 
    :loop 
    fc nul /n | find " 1:" > setfile.bat 
    if errorlevel 1 goto restore 
    debug setfile.bat nul 
    call setfile.bat 
    dir "%file%" | find %info% > nul 
    if not errorlevel 1 echo Visit file: "%file%" 
    :: if not errorlevel 1 
    find "%file%" /v 
    :: "%file%" 参数决定了所匹配的子目录下的所有文件和目录均不会再次匹配 
    copy > nul 
    goto loop 
    :restore 
    if exist del 
    if exist del 
    if exist del 
    if exist setfile.bat del setfile.bat 
    set info= 
    set file= 
    set base= 
    :end 



    Visit.bat - 文件遍历批处理程序 

    复制代码代码如下:

    :: Visit.bat - 文件遍历批处理程序 
    :: Will Sort - 10/17/2004 - V2 
    :: 
    :: 程序用途: 
    :: 对指定文件集/目录集/文件列表执行指定操作 
    :: 
    :: 命令行说明: 
    :: 1. VISIT 文件集/目录集 [参数] 
    :: 对文件集/目录集执行指定操作 
    :: 2. VISIT @ 文件列表 
    :: 对指定文件列表中的文件执行指定操作 
    :: 
    :: 注意事项: 
    :: - 文件集/目录集 中可包含有效路径和通配符 
    :: - 路径缺省为当前路径,文件集缺省为 *.* (并非所有文件) 
    :: - 文件集/目录集 含空格时需用双引号引起 
    :: - [参数] 支持的DIR开关: /S /A /O /L等不与 /B 冲突者 
    :: - [参数] 不支持的DIR开关: /W /P /V 等与 /B 冲突者 
    :: - [操作] 由调用者预先写入 visitcmd.bat 中 
    :: - [操作] 中使用 %VisitFile% 引用遍历文件 
    :: - 程序检查检查 [文件列表] 是否存在,但不检查它是否有效 
    :: - 不遍历隐藏/系统目录下的目录和文件(在命令行中指定时例外) 
    :: 
    :: 用法示例: 
    :: visit c: /ad /s 遍历C盘所有目录,包含子目录 
    :: visit "C:My document" /a-d 遍历"C:My document"下所有文件 
    :: visit C:*.zip /a /s 遍历C盘所有.zip压缩包,包含子目录 
    :: 如想遍历多个文件/目录集,可多次使用"DIR 文件集 /a /s>>文件列表" 
    :: 生成一个完整的文件列表,再使用文件列表进行遍历;或者使用VisitCE.Bat 
    :: 在遍历未显式指定的隐藏/系统目录时,可以用"attrib 文件集 /s"生成 
    :: 文件列表,然后在visitcmd.bat的代码中引用%VisitFile%第三至最后的串, 
    :: 再使用文件列表进行遍历 
    :: 
    :: 测试报告: 
    :: 在 Win98 命令行方式下有限黑箱测试通过 
    :: 性能仍然是最大的瓶颈 
    :: 
     1 @echo off 
     2 if "%1"=="@" goto CopyList 
     3 :MakeList 
     4 dir /b %1 %2 %3 %4 %5 %6 > ~ 
     5 find "~" /v < ~ > ~ 
     6 if not errorlevel 1 copy ~ ~>nul 
     7 goto MakePreLine 
     8 :CopyList 
     9 if not [%2]==[] if exist %2 copy %2 ~>nul 
    10 if not exist ~ goto End 
    11 :MakePreLine 
    12 echo set VisitFile=> ~ 
    13 for %%c in (rcx e w q) do echo %%c>> ~ 
    14 debug ~ < ~ > nul 
    15 if [%OS%]==[Windows_NT] chcp 936 > nul 
    16 :LoopVisit 
    17 copy ~+~ ~ > nul 
    18 find "set VisitFile=" < ~ > ~visit.bat 
    19 call ~visit.bat 
    20 if "%VisitFile%"=="" goto Clear 
    21 if not exist visitcmd.bat echo Visiting %VisitFile% 
    22 if exist visitcmd.bat call visitcmd.bat 
    23 find "set VisitFile=" /v < ~ > ~ 
    24 goto LoopVisit 
    25 :Clear 
    26 del ~visit.* 
    27 set VisitFile= 
    28 :End 


    VisitCE.bat - 文件遍历批处理程序命令行增强版 

    复制代码代码如下:

    :: VisitCE.bat - 文件遍历批处理程序命令行增强版 
    :: Will Sort - 10/17/2004 - V2CE 
    :: 
    :: 程序用途: 
    :: 对指定路径/文件列表下的指定文件/目录集执行指定操作 
    :: 
    :: 命令行说明: 
    :: 1. VISIT [路径1 路径2...] [开关1 开关2...] [文件集1 文件集2...] 
    :: 对 [路径] 和 [开关] 限定下的 [文件集] 执行指定操作 
    :: 2. VISIT @ 文件列表1 [文件列表2...] 
    :: 对指定 [文件列表] 中的文件执行指定操作 
    :: 
    :: 注意事项: 
    :: - [路径] [参数] [文件集] 均可不选或多选 
    :: - [路径] 中不可包含通配符,[文件集] 中可包含有效路径和通配符 
    :: - [路径] 缺省为当前路径,[文件集] 缺省为 *.* (并非所有文件) 
    :: - [路径] [文件集] 含空格时需用双引号引起 
    :: - [参数] 支持的DIR开关: /S /A /O /L等不与 /B 冲突者 
    :: - [参数] 不支持的DIR开关: /W /P /V 等与 /B 冲突者 
    :: - [操作] 由调用者预先写入 visitcmd.bat 中 
    :: - [操作] 中使用 %VisitFile% 引用遍历文件 
    :: - 程序检查检查 [文件列表] 是否存在,但不检查它是否有效 
    :: - 不遍历隐藏/系统目录下的目录和文件(在命令行中指定时例外) 
    :: 
    :: 用法示例: 
    :: visit c: /ad /s 遍历C盘所有目录,包含所有子目录 
    :: visit "C:My document" /a-d 遍历"C:My document"下所有文件 
    :: visit c: d: e: /s /a /on 遍历C,D,E中所有文件,并按文件名排序 
    :: visit /a 遍历当前盘根目下所有文件和目录 
    :: 在遍历未显式指定的隐藏/系统目录时,可以用"attrib 文件集 /s"生成 
    :: 文件列表,然后在visitcmd.bat的代码中引用%VisitFile%第三至最后的串, 
    :: 再使用文件列表进行遍历 
    :: 
    :: 测试报告: 
    :: 在 Win98 命令行方式下有限黑箱测试通过 
    :: 性能仍然是最大的瓶颈 
    :: 
     1 @echo off 
     2 if "%1"=="$" goto MakeList 
     3 if "%1"=="@" goto CopyList 
     4 if "%1"=="" goto End 
     5 set VisitCommand=%0 
     6 :GetArgu 
     7 :GetPath 
     8 if not exist %1.
    ul goto GetSwitch 
     9 set VisitPath=%VisitPath% %1 
    10 goto GetNext 
    11 :GetSwitch 
    12 echo %1 | find "/" > nul 
    13 if errorlevel 1 goto GetFilter 
    14 set VisitSwitch=%VisitSwitch% %1 
    15 goto GetNext 
    16 :GetFilter 
    17 echo %1 | find "*" > nul 
    18 if not errorlevel 1 goto SetFilter 
    19 echo %1 | find "?" > nul 
    20 if errorlevel 1 goto End 
    21 :SetFilter 
    22 set VisitFilter=%VisitFilter% %1 
    23 :GetNext 
    24 shift 
    25 if not [%1]==[] goto GetArgu 
    26 %VisitCommand% $ %VisitFilter% 
    27 :MakeList 
    28 if not [%VisitPath%]==[] goto ForMake 
    29 :DirMake 
    30 dir %2 /b %VisitSwitch% >> ~ 
    31 goto MakeNext 
    32 :ForMake 
    33 for %%p in (%VisitPath%) do dir %%p.%2 /b %VisitSwitch% >> ~ 
    34 :MakeNext 
    35 shift 
    36 if not [%2]==[] goto MakeList 
    37 find "~" /v < ~ > ~ 
    38 if not errorlevel 1 copy ~ ~>nul 
    39 goto MakePreLine 
    40 :CopyList 
    41 if not [%2]==[] if exist %2 type %2>>~ 
    42 shift 
    43 if not [%2]==[] goto CopyList 
    44 :MakePreLine 
    45 if not exist ~ goto End 
    46 echo set VisitFile=> ~ 
    47 for %%c in (rcx e w q) do echo %%c>> ~ 
    48 debug ~ < ~ > nul 
    49 if [%OS%]==[Windows_NT] chcp 936 > nul 
    50 :LoopVisit 
    51 copy ~+~ ~ > nul 
    52 find "set VisitFile=" < ~ > ~visit.bat 
    53 call ~visit.bat 
    54 if "%VisitFile%"=="" goto Clear 
    55 if not exist visitcmd.bat echo Visiting %VisitPath% %VisitSwitch% %VisitFilter% - %VisitFile% 
    56 if exist visitcmd.bat call visitcmd.bat 
    57 find "set VisitFile=" /v < ~ > ~ 
    58 goto LoopVisit 
    59 :Clear 
    60 for %%f in (~visit.*) do del %%f 
    61 for %%e in (Command Path Switch Filter File) do set Visit%%e= 
    62 :End 


    在2000sp4 下出现类似的问题,第二个问题实际上也是fc的不兼容问题,他在按行号显示时,每行文字前有8 个字节位,而不是dos6和win9x 下的9 个,所以解决起来也很简单,将debug 脚本中的 e 100 'set file='改为 e 100 'set fil=' 即可。 

      但是,这只是就事论事而已,以上的提到的三个批处理,只是我在dos 下练兵用的试验原型,做得很粗糙,自从今年3 月份正式转向win98 之后,使用中遇到了很多新问题,比如文件名包含空格的问题,系统/ 隐藏属性目录的问题;在nt下使用,又遇到了中文文件名的问题;而且由于循环体中使用了过多的文本流控制,导致了效率的严重低下;另外,三个程序功能上和实现上并没有太大的差别,没有拆分的必要。 
      综所上述,将以上代码重写就成为必须。合并代码,弥补漏洞,改善性能,书写文档,就出现了所谓的 V2 版,这中间其实并没有花很多功夫。 

      然而,一个偶然的下午,突然心血来潮,何不将visit 的命令行功能做一下增强,比如支持多个路径、多个过滤器(filter)、多个文件列表,原想只是加一个命令行参数分析循环,然而真正实现起来,却再次体会到了命令行的复杂,if for嵌套时冲定向输出,判定目录时根目录与子目录的不同,for 对过滤器的低能替换(win9x/dos) ,一个个新问题摩肩接踵,层出不穷,竟然整整耗了我大半个工作日的时间,才勉强实现了一个粗糙的版本,这就是所谓的 V2CE 版,对与严格的测试我没有多大的信心。 

      现在,再回头看我的工作,其实那个 V2CE 版其实是没有多大的应用价值。多个路径和过滤器,完全可以通过多次调用visit 来实现,而且实际上,我们大多数情况下只用一个路径和过滤器;而且,多参数控制带来了易用度的下降,用户总是对参数繁多的程序有一定的心理障碍,我个人对dos 压缩软件的爱好,从高到低依次是rar,zip,arj, 易用度就是第一靠量;另外,最重要的是,多参数控制导致了代码量和复杂性的大幅提升,这个程序一度让我钻进了if for构建的幽魂迷宫而不知南北西东,程序的可读性越来越差,调试起来也越来越困难,同时兼容性上拉上了更多的绊马索。 

      这些,就是功能提升所付出的代价,虽然这只是一个比较极端的例子,但是功能与简洁的平衡在程序设计的其重要性可见一斑。亲和性的界面并不意味着亲和性的代码,人性化的需求并不意味着人性化的实现,一味将使用方的复杂性转嫁给设计者(比如Windows), 并不是一个很聪明的主意,反之亦然(比如Linux ),这尚不考虑代码功能增强对设计方和使用方的双重施压。

    转自:http://www.jb51.net/article/31285.htm

  • 相关阅读:
    <剑指OFFER18> 18_01_DeleteNodeInList在O(1)时间删除链表结点
    哈夫曼树

    快速排序
    冒泡算法
    Java 缓存机制
    JAVA NIO
    string、stringbuilder、stringbuffer区别
    Java内存泄露的问题调查定位
    使用hibernate 框架搭建的helloworld
  • 原文地址:https://www.cnblogs.com/zl1991/p/8297430.html
Copyright © 2011-2022 走看看