标题: [文件操作] [已解决]BAT批处理如何列只列出只底层的目录? [打印本页]
作者: zhao3 时间: 2014-5-9 18:01 标题: [已解决]BAT批处理如何列只列出只底层的目录?
本帖最后由 zhao3 于 2014-5-13 23:55 编辑
示例:我的D盘有以下目录
D:\A1\A11\A111\A1111
D:\A1\A12\A121\
D:\A2\A23\
D:\A3\
D:\A4\
D:\A5\
现在我想得到如下输出:
D:\A1\A11\A111\A1111
D:\A1\A12\A121\
D:\A2\A23\
D:\A3\
D:\A4\
D:\A5\
使用TREE命令,会出现各级目录,而我不需要出现含有子目录的目录名
D:\A1\
D:\A2\
D:\A1\A11\
D:\A1\A12\
D:\A1\A11\A111\
先谢谢各位大侠了。。
作者: apang 时间: 2014-5-9 21:08
- @echo off
- for /d /r "D:\" %%a in (*) do (
- for /d %%b in ("%%a\*") do set a=1
- if defined a (set a=) else echo,%%a
- )
复制代码
作者: CrLf 时间: 2014-5-9 21:34
本帖最后由 CrLf 于 2014-5-10 04:28 编辑
算了还是用 bat + js 吧,各取其长:- @if (0)==(0) echo off
- dir /ad /s /b | cscript /nologo /e:jscript %0 >a.txt
- pause&exit/b
- @end
-
- var text = WScript.StdIn.ReadAll().replace(/\r?\n/g,'\\\n').toLowerCase()
-
- var ar = text.split(/\n/).sort()
- for(var i=ar.length-1;i--;){
- if(ar[i+1].indexOf(ar[i])==0){ar.splice(i,1)}
- }
-
- text = ar.join('\r\n').replace(/\\$/gm,'')
- WScript.Echo(text)
复制代码
作者: CrLf 时间: 2014-5-9 22:01
本帖最后由 CrLf 于 2014-5-9 23:01 编辑
powershell 方案:- $dr = get-childitem -Recurse
- $text = ForEach($_ in $dr){
- if($_.PSIsContainer){
- if(!$_.GetDirectories()){$_.FullName}
- }
- )
- Set-Content -Encoding String -Value $text a.txt
复制代码
- Function list($Obj)
- {
- if($DS = $Obj.GetDirectories()){
- foreach($D in $DS){
- list $D
- }
- } else {
- $Obj.FullName
- }
- }
-
- list (get-item .) | Set-Content -Encoding String a.txt
复制代码
作者: zhao3 时间: 2014-5-9 22:19
谢谢二楼,三楼,真的很谢谢你们。
我用的CrLf的方案,执行效果很好,60K的文件30S+就完成了,太棒了。
另请问一下,保存得到的文件是相当于是逆序保存的,能正序保存吗,如果不难的话,正序最好了,当然我可以在excel中倒一下也行。
=======================================
如果你是老师,我可以为你提供一些系统的教学资源;
如果你的孩子还是幼儿,我可以为你提供一些幼教资源;
如果以上资源你都用不上,请PM我一下您的话,我充一点话费,略表心意。
作者: zhao3 时间: 2014-5-9 22:20
如果以上资源你都用不上,请PM我一下您的电话,我充一点话费,略表心意。
作者: CrLf 时间: 2014-5-9 22:28
顺序保存只需要 sort 一下就行:复制代码
作者: CrLf 时间: 2014-5-9 22:29
回复 5# zhao3
楼主太客气了
作者: zhao3 时间: 2014-5-9 22:35
太强大了。。。。
成功,谢谢。
还是pm一下吧。
哈哈。。。。
作者: apang 时间: 2014-5-9 23:00
回复 3# CrLf
Microsoft Windows [版本 6.1.7601]
版权所有 (c) 2009 Microsoft Corporation。保留所有权利。
C:\Windows\System32>cd /d d:\test\
d:\test>dir /b /ad /s | sort /r
d:\test\新建文件夹\新建文件夹 - 副本
d:\test\新建文件夹 (2)\abc
d:\test\新建文件夹 (2)
d:\test\新建文件夹
d:\test>
这种情况下,貌似上下行比较会误判?
作者: CrLf 时间: 2014-5-9 23:02
回复 10# apang
用的是 !last:%%a\=!,好像不会误判吧
作者: zhao3 时间: 2014-5-9 23:12
那跟贴再问一问:
提取目录内的第一个文件名作为目录名
因为目录名是无序的数字,里在文件名有意义。
作者: CrLf 时间: 2014-5-9 23:19
回复 12# zhao3
不同问题请单独开贴
作者: apang 时间: 2014-5-9 23:35
回复 11# CrLf
Microsoft Windows [版本 6.1.7601]
版权所有 (c) 2009 Microsoft Corporation。保留所有权利。
C:\Windows\System32>cd /d d:\test\
d:\test>dir /b /ad /s | sort/r
d:\test\新建文件夹\新建文件夹 - 副本
d:\test\新建文件夹 2\abc
d:\test\新建文件夹 2
d:\test\新建文件夹
d:\test\abc
d:\test>test.bat
d:\test\新建文件夹\新建文件夹 - 副本
d:\test\新建文件夹 2\abc
d:\test\新建文件夹
请按任意键继续. . .
d:\test>
d:\test\新建文件夹 这一行按理说不应该显示出来?
作者: zhao3 时间: 2014-5-9 23:42
我的本意,是没有子目录的目录都列出来。有子目录的,列最底层目录。
作者: CrLf 时间: 2014-5-9 23:52
回复 14# apang
确实如此,忽略了 \ 会影响排序,谢谢提醒
代码已更新,小改成完全逆序,就不存在这个问题了
作者: zhao3 时间: 2014-5-10 01:54
正准备反映一个问题的,就是最后一个文件会被忽略。。。
作者: zhao3 时间: 2014-5-10 02:04
由于是逆序排列,实际遗失是的第一个目录下的第一个被记录的目录名
(for /f "delims=" %%a in ('dir /ad /s /b^|sort /+65535') do (
新改的代码,将所有的目录列举了,相当于是tree的效果。
作者: CrLf 时间: 2014-5-10 02:52
回复 18# zhao3
卧槽,好吧又掉坑里了,已修改
作者: zhanglei1371 时间: 2014-5-10 10:05
回复 3# CrLf
想请教下,这种形式的写法该如何调试,单纯批处理我可以用pause和echo来查看变量的值,然后根据值的变化来对代码修正,这种情况该如何查看一个变量的值,如里面的数组ar,另外,我试了下加pause来暂停,发现没用。还望指点下,谢谢
作者: CrLf 时间: 2014-5-10 17:35
回复 20# zhanglei1371
可以这样玩下:- var cmd = new Command()
-
- var str = cmd.set.p('请输入任意算式,回车确定\n')
- try{
- cmd.set.a('Num='+str)
- cmd.echo('结果是:'+Num)
- }
- catch(e){
- cmd.echo(Num)
- cmd.exit(1)
- }
- cmd.set.p('任意键退出')
-
- function Command(){
- this.echo = function (str){WScript.Echo(str)}
- this.exit = function (num){WScript.Quit(num)}
- this.set = {
- a:function (str){eval(str)},
- p:function (str){
- WScript.StdOut.Write(str)
- return WScript.StdIn.ReadLine()
- }
- }
- }
复制代码
作者: zhanglei1371 时间: 2014-5-10 20:14
回复 21# CrLf
我存为js文件,运行后,出现:
作者: CrLf 时间: 2014-5-10 20:49
回复 22# zhanglei1371
js 默认用 wscript 运行,此时不支持 StdIn、StdOut、StdErr
解决方法有两个,一个是用 cscript 运行,另一个是用 fso.GetStandardStream(N)
参考
建议用 cscript 运行,比如这样保存为 bat:- @set @n=0/*&echo off
- cscript -nologo -e:jscript %0
- pause & exit /b
- */
- var cmd = new Command()
-
- var str = cmd.set.p('请输入任意算式,回车确定\n')
- try{
- cmd.set.a('Num='+str)
- cmd.echo('结果是:'+Num)
- }
- catch(e){
- cmd.echo(Num)
- cmd.exit(1)
- }
- cmd.set.p('任意键退出')
-
- function Command(){
- this.echo = function (str){WScript.Echo(str)}
- this.exit = function (num){WScript.Quit(num)}
- this.set = {
- a:function (str){eval(str)},
- p:function (str){
- WScript.StdOut.Write(str)
- return WScript.StdIn.ReadLine()
- }
- }
- }
复制代码
作者: CrLf 时间: 2014-5-10 20:54
回复 22# zhanglei1371
这种写法修改自 powerbat 的混编方案:- @set @n=0/*
- batCode
- exit /b
- */
- jsCode
复制代码
terse 修改出了另一种写法,不需要写变量:- @if (0)==(0) echo off
- batCode
- exit /b
- @end
- jsCode
复制代码
二者各有千秋,随便哪个都可以
作者: zhanglei1371 时间: 2014-5-10 21:27
本帖最后由 zhanglei1371 于 2014-5-10 21:29 编辑
回复 24# CrLf
Many Thx!!!最后一点,我把前面三楼你的代码列出,去掉后面的>a.txt,然后,在中间加上一句:WScript.Echo(ar),不过,怎么才能像上面的command()例子代码中一样,显示一个,按任意键后,再出现下一个?- @if (0)==(0) echo off
- dir /ad /s /b | cscript /nologo /e:jscript %0
- pause&exit/b
- @end
-
- var text = WScript.StdIn.ReadAll().replace(/\r?\n/g,'\\\n').toLowerCase()
-
- var ar = text.split(/\n/).sort()
- for(var i=ar.length-1;i--;){
- WScript.Echo(ar[i]) //这里怎么能查看一次,暂停一下,按任意键后再显示下一个?
-
- if(ar[i+1].indexOf(ar[i])==0){ar.splice(i,1)}
- }
复制代码
作者: CrLf 时间: 2014-5-10 22:17
回复 25# zhanglei1371
最简单的是虚拟一个 system 函数,想 dir 或者 echo 什么的用它就可以了,不过和 c 的 system 函数一样需要调用外部程序,效率比较低- System('pause')
-
- function System(commadline){
- var ws = new ActiveXObject('WScript.Shell')
- return ws.Exec('cmd /c '+commandline)
- }
复制代码
作者: zhanglei1371 时间: 2014-5-10 22:37
回复 26# CrLf
我用如下代码测试,似乎起不到暂停作用:- @if (0)==(0) echo off
- cscript /nologo /e:jscript %0
- pause&exit/b
- @end
-
- WScript.echo('sdfsdfsdfsdfsdfsdfsd0000123')
- System('pause')
- WScript.echo('sdfsdfsdfsdfsdfsdfsd0000123')
-
- function System(commandline){
- var ws = new ActiveXObject('WScript.Shell')
- return ws.Exec('cmd /c '+commandline)
- }
复制代码
怎么回事?是否我的代码哪里有误?
作者: CrLf 时间: 2014-5-11 00:04
回复 27# zhanglei1371
卧槽,ws.Exec 不给力,那用 ws.Popup 之类的吧,反正起到暂停效果了
作者: terse 时间: 2014-5-12 19:25
用纯P搞它- @echo off
- for /d /r %%a in (*) do (
- (for /f %%b in ('dir /ad/b %%a') do break)||(
- echo %%a
- pause
- )
- )
- pause
复制代码
作者: CrLf 时间: 2014-5-12 22:04
回复 29# terse
新姿势get!
但没想明白,%%a 无取值的 for /f 为什么会这样调皮:- (for /f %%a in ('dir /ad /b test') do break)&echo !errorlevel!
- (for /f %%a in ('dir /ad /b test') do break)||echo !errorlevel!
复制代码
看来可以推翻 qzw 胸“管道符与重定向,如 |,&,||,&&,>,>>,1>,2> 等不改变 errorlevel” 的说法了:http://bbs.bathome.net/viewthread.php?tid=7479
作者: qzwqzw 时间: 2014-11-24 22:55
回复 30# CrLf
这个问题终于有了分析结果
http://www.bathome.net/redirect. ... 02&fromuid=3023
作者: amwfjhh 时间: 2014-11-24 23:07
精彩!!!
作者: amwfjhh 时间: 2014-11-25 00:02
回复 16# CrLf
回车 兄头脑里那么多脚本方案,遇到待处理问题的时候它们会不会在头脑里打架哦……
作者: CrLf 时间: 2014-11-25 00:34
回复 33# amwfjhh
也就批处理最熟,其他都只是半入门状态,脑子已经有点乱了,所以更不敢碰 c++ 什么的
作者: tttggg 时间: 2014-11-25 17:35
:victory::victory::victory::victory::victory:
欢迎光临 批处理之家 (http://bbs.bathome.net/) |
Powered by Discuz! 7.2 |