标题: [文本处理] 批处理如何用dir命令列磁盘文件时排除一个或多个文件夹? [打印本页]
作者: newfish 时间: 2011-8-4 17:41 标题: 批处理如何用dir命令列磁盘文件时排除一个或多个文件夹?
dir c:\ /b | findstr /v /x "WINDOWS"
这句可以排除WINDOWS目录(WINDOWS必须为大写)
可是加/s参数 dir /s c:\ /b | findstr /v /x "WINDOWS" 就不行 。。
我修改代码如下报错 此时不应有 “|”
for /f %%i in ('dir c:\ /b | findstr /v /x "WINDOWS"') do ('dir /s c:\%%i >1.txt')
问题:
如何用dir /s 列磁盘文件的时侯,排除一个或多个文件夹
作者: CrLf 时间: 2011-8-4 17:45
这里的 | 需要转义:- for /f %%i in ('dir c:\ /b ^| findstr /v /x "WINDOWS"') do ('dir /s c:\%%i >1.txt')
复制代码
或者- for /f %%i in ('"dir c:\ /b | findstr /v /x "WINDOWS""') do ('dir /s c:\%%i >1.txt')
复制代码
作者: newfish 时间: 2011-8-4 17:47
原来如此 ..感谢版主! in 里面的 应当是文本来处理来着...明白了 !!!
作者: CrLf 时间: 2011-8-4 17:52
不是当文本处理,而是作为参数传递给新的 cmd 进程,以下解释转自批处理吧:
for /f 从命令获取输入时,将启用新的 cmd 进程来解释执行 '号对之间的内容,也就是要经历两次预处理,在 for 中一次、cmd 中又一次,而这些内容中若包含特殊字符,将导致for命令被错误划分。
那行代码执行时,dir /b /ad /s c:\^|sort /r 将作为 cmd /c 的参数执行,也就是 cmd /c dir /b /ad /s c:\^|sort /r,| 在第一次预处理中被转义为普通字符,到了新的 cmd 进程中才起到了管道符应有的作用。
当然,同样可以用双引号来转义整个参数,而无需挨个转义所有特殊字符——既然 cmd /c "dir /b /ad /s c:\|sort /r" 成立,那同样可以在 for /f 中这么做,所以这样写也是可以的:for /f "delims=" %%a in ('"dir /b /ad /s c:\|sort /r"') do rd /q %%a 2>nul
顺便说一下,因为 for /f 从命令获取输入时是从新的 cmd 进程中获取其输出,这些输入的信息在被读取之前都是停留在内存中的,所以其效率不如将输入重定向到文本、再用 for /f 从文件获取输入来得高,不过具体情况具体分析,并无所谓哪种方法一定是最好的。另外,这不宜在循环中使用,因为那将循环开启新的 cmd,效率等同于重复循环使用 findstr、sort 等外部命令。
作者: newfish 时间: 2011-8-4 18:22
本帖最后由 newfish 于 2011-8-4 18:31 编辑
这段代码 总感觉鸡肋 的很.
鸡肋的原因
dir/s 会连带之前 dir 出来的文件 也就是会出现 dir /s c:\123.txt 但是在最后输出的时候并不能看到这些文件名,,特别苦恼!
求解决办法!
别且罗列出来的是追加出来的那种 和本身的 dir/s 输出的格式有出入 ~~~郁闷
作者: CrLf 时间: 2011-8-4 18:37
回复 5# newfish
不明白,可否检查一下 %dircmd% 是否为空
作者: newfish 时间: 2011-8-5 06:11
这样写效率超级低..还不如不排除 windows..目录..
能否在不降低效率的情况下 dir /s c盘 并跳过 c盘下windows和它的子目录
作者: CrLf 时间: 2011-8-5 11:59
提高效率的办法是将一次 dir 的输出重定向到文件,然后用 for 排除,不过要想完全模拟顶楼代码,估计效率恐怕也不怎么滴,而且代码很长,费力不讨好:- @echo off&setlocal enabledelayedexpansion
- set dircmd=C:\
- dir /s|findstr /n /v /r /c:"所列文件总数" /c:"Total Files Listed" /c:"^[ 0-9]*Dir" /c:"^[ 0-9]*个目录">tmp.txt
- for /f "delims=:" %%a in ('find /c /v ""^<tmp.txt') do set /a all=%%a-1
- (for /f "delims==" %%a in ('set') do set %%a=
- set all=%all%
- set /p a=&set /p b=)<tmp.txt
- for /f "tokens=1*" %%a in ('dir') do set end=%%b
- for /f %%a in ('copy /z %0 nul') do set hh=%%a^
-
-
- (for /f "tokens=1* skip=3 delims=:" %%a in (tmp.txt) do (
- if %%a lss %all% (
- for /f "eol=2 tokens=1,2 delims=\" %%c in ("%%b") do (
- if /i "%%c"==" C:" (
- if /i "%%c\%%d"==" C:\Windows" (
- set echo=
- ) else (
- set echo=1
- echo %a:~2%!hh!%b:~2%!hh!
- )
- ) else (
- set "str= !n!"
- set n=-2
- echo !str:~-16! %end%
- set str=
- )
- )
- if defined echo echo;%%b
- for /f "tokens=2 delims=<>" %%c in ("%%b") do (
- if /i %%c==DIR set /a n+=1
- )
- )
- ))>结果.txt
- del /f tmp.txt>nul
- pause
复制代码
为了省事,此代码不考虑文件名中的特殊字符...
作者: Hello123World 时间: 2011-8-5 17:55
- @echo off
- (For /f "delims=" %%i in ('dir /s /b c:\ ^| Findstr /v "WINDOWS"') do echo %%i )>1.txt
- pause
复制代码
在括号中使用管道符|需要在前面加一个转义字符^。
欢迎光临 批处理之家 (http://bathome.net./) |
Powered by Discuz! 7.2 |