中国DOS联盟论坛

中国DOS联盟

-- 联合DOS 推动DOS 发展DOS --

联盟域名:www.cn-dos.net  论坛域名:www.cn-dos.net/forum
DOS,代表着自由开放与发展,我们努力起来,学习FreeDOS和Linux的自由开放与GNU精神,共同创造和发展美好的自由与GNU GPL世界吧!

游客:  注册 | 登录 | 命令行 | 会员 | 搜索 | 上传 | 帮助 »
中国DOS联盟论坛 » DOS批处理 & 脚本技术(批处理室) » [问题]关于for与findstr查找并删除空文件夹的问题
« [1] [2] »
作者:
标题: [问题]关于for与findstr查找并删除空文件夹的问题 上一主题 | 下一主题
voiL
中级用户





积分 384
发帖 189
注册 2005-10-19
状态 离线
『楼 主』:  [问题]关于for与findstr查找并删除空文件夹的问题

声明: 1,2楼代码皆运行于XP sp2环境下.

因工作需要,我每天都要在工作目录下建立好多以当天日期命名的目录(各子目录都有可能建立),但有时难免建立了目录之后,没有往里面装文件.时间一长就会积累了很多的空目录.人手删除是没什么可能的了.所以想用批处理来完成,但遇到了一个问题:

程序对于含有特殊字符或者空格的目录没办法正确处理.

在些请教论坛上一些for和findstr的高手,看有没什么好的办法.
::***/// 设置目标目录 \\\***
set keyword1=m:\test\
::***/// 设置需要删除的文件夹名字(因有些文件夹不想删) \\\***
set keyword2=2006-12-

::***/// 创建临时文件与目录 \\\***
cd.>nuldir.txt
cd.>nuldir2.txt
md 目录回收
::***/// 列举当前目录下所有目录名字,并输出到nuldir.txt \\\***
for /f "delims=" %%i in ('dir /ad /b /s') do (dir /a /b "%%i"|findstr .>nul||echo %%i>>nuldir.txt)
::***/// 在nuldir.txt排除指定条件的目录并写到nuldir2.txt \\\***
for /f "delims=%keyword1% tokens=1*" %%i in (nuldir.txt) do echo %%j>>nuldir2.txt
type nuldir2.txt | findstr /i "%keyword2%">nuldir.txt
::***/// 在"目录回收"下建立新目录并删除原目录 \\\***
for /f %%i in (nuldir2.txt) do md 目录回收\%%i && del /q %%i
::***/// 删除临时文件 \\\***
del /q nuldir.txt & rd /q nuldir2.txt
[ Last edited by voiL on 2006-12-26 at 04:33 AM ]

2006-12-26 00:05
查看资料  发短消息 网志   编辑帖子  回复  引用回复
voiL
中级用户





积分 384
发帖 189
注册 2005-10-19
状态 离线
『第 2 楼』:  


以下脚本也是我日常工作的批处理.

为了工作方便,我把它做成可以直接把文件拖进行然后选择目标目录就可以了.

但也遇到一个问题,如果文件名有特殊字符就不能正确处理了.

在此也请教一下高手们,看有什么好的解决方法没有.

看了论坛上一些关于防空字符和特殊字符过滤的文章,也无济于事.

毕竟我起步晚,对编程也不懂,只懂得平时玩玩一些简单的批处理.

现在才后悔莫及.

@echo off
color 17
mode con lines=25 cols=80
set targetdir1=n:\政府网站
set targetdir2=n:\乡镇网站

:input
cls & echo.
echo  =======================本程序只可正常运行于Windows XP下=======================
echo.
echo                    ┏━━━━━━请选择目录━━━━━━┓
echo                    ┃                                  ┃
echo                    ┃ [1] 政府网站      [2] 乡镇网站   ┃
echo                    ┃                                  ┃
echo                    ┃ [H] 阅读说明        [X] 退出程序 ┃
echo                    ┃                                  ┃
echo                    ┗━━━━━━━━━━━━━━━━━┛
echo.
echo  ==============================================================================
echo.
set /p choose= 请输入位速代号:
for %%i in (1 2 h H x X) do if "%choose%" == "%%i" goto check
echo  & cls
echo.
echo.
echo                      ┏━━━━━━ 注  意 ━━━━━━┓
echo                      ┃                                ┃
echo                      ┃ 你输入参数不正确! 请重新输入!  ┃
echo                      ┃                                ┃
echo                      ┗━━━━━━━━━━━━━━━━┛
ping  1.1 -n 1 -w 2000>nul
goto input

:check
for %%i in (%*) do if "!%%i" == "!" goto nofiles
if "%choose%" == "1" goto gov
if "%choose%" == "2" goto town
if "%choose%" == "x" exit
if "%choose%" == "X" exit
if "%choose%" == "h" goto help
if "%choose%" == "H" goto help
echo  & cls
echo.
echo.
echo                      ┏━━━━━━ 注  意 ━━━━━━┓
echo                      ┃                                ┃
echo                      ┃   程序出现意外,3秒后退出...   ┃
echo                      ┃                                ┃
echo                      ┗━━━━━━━━━━━━━━━━┛
goto end

:gov
cls
if not exist %targetdir1%\nul goto nodir
dir %1\. >nul 2>nul && goto nofolder
echo.
echo.
echo                ┏━━━━━━━━━━━━━━━━━━━━━━━┓
echo                ┃                                              ┃
echo                ┃正在复制文件到 〖政府网站〗 目录下,请稍候... ┃
echo                ┃                                              ┃
echo                ┗━━━━━━━━━━━━━━━━━━━━━━━┛
copy /y %1 %targetdir1% 2>nul 1>nul
if %2! == ! goto nextgov
Shift
goto gov

:nextgov
cls
echo.
echo.
echo              ┏━━━━━━━━━━━━━━━━━━━━━━━━━┓
echo              ┃                                                  ┃
echo              ┃文件已成功复制到 〖政府网站〗 目录下,3秒后退出...┃
echo              ┃                                                  ┃
echo              ┗━━━━━━━━━━━━━━━━━━━━━━━━━┛
goto end

:town
cls
if not exist %targetdir1%\nul goto nodir
dir %1\. >nul 2>nul && goto nofolder
echo.
echo.
echo                ┏━━━━━━━━━━━━━━━━━━━━━━━┓
echo                ┃                                              ┃
echo                ┃正在复制文件到 〖乡镇网站〗 目录下,请稍候... ┃
echo                ┃                                              ┃
echo                ┗━━━━━━━━━━━━━━━━━━━━━━━┛
copy /y %1 %targetdir2% 2>nul 1>nul
if %2! == ! goto nexttown
Shift
goto town

:nexttown
cls
echo.
echo.
echo              ┏━━━━━━━━━━━━━━━━━━━━━━━━━┓
echo              ┃                                                  ┃
echo              ┃文件已成功复制到 〖乡镇网站〗 目录下,3秒后退出...┃
echo              ┃                                                  ┃
echo              ┗━━━━━━━━━━━━━━━━━━━━━━━━━┛
goto end

.................................

:end
ping 1.1 -n 1 -w 3000 >nul 2>nul
exit
[ Last edited by voiL on 2006-12-26 at 11:50 PM ]

2006-12-26 00:06
查看资料  发短消息 网志   编辑帖子  回复  引用回复
namejm
荣誉版主

batch fan


积分 5226
发帖 1737
注册 2006-3-10
来自 成都
状态 离线
『第 3 楼』:  

  只考虑删除当前目录下及其所有子目录的所有空文件夹,可以考虑先把所有的文件夹 dir 出来之后,再利用 rd 不能删除非空目录的特点来删除空文件夹。比如如下演示代码:
  ———————————————————————————————————————
  这个方案有考虑不周的地方,请看5楼的描述。
@echo off
:: 请创建测试目录来测试,否则不会有效果;请勿在工作目录下测试,否则后悔莫及。
for /f "delims=" %%i in ('dir /ad /b /s') do rd "%%i" 2>nul
  至于只删除当前目录下及其子目录中以日期命名的空文件夹,稍后再讨论,吃饭去了先~~

[ Last edited by namejm on 2006-12-25 at 06:43 PM ]

   此帖被 +4 点积分        点击查看详情   
评分人:【 voiL 分数: +4  时间:2006-12-26 22:18




尺有所短,寸有所长,学好CMD没商量。
考虑问题复杂化,解决问题简洁化。
2006-12-26 00:33
查看资料  发短消息 网志   编辑帖子  回复  引用回复
a9319751
中级用户





积分 439
发帖 170
注册 2006-1-9
状态 离线
『第 4 楼』:  

举个例子,什么特殊字符,
参数加""试试



bat c c++
2006-12-26 00:37
查看资料  发送邮件  发短消息 网志  OICQ (5040366)  编辑帖子  回复  引用回复
namejm
荣誉版主

batch fan


积分 5226
发帖 1737
注册 2006-3-10
来自 成都
状态 离线
『第 5 楼』:  

  3楼的代码还有欠考虑的地方,因为:如果某个深层目录下只有空文件夹的话,删掉最深层的那个空文件夹之后,它上面的那个目录又变为空了,而在这之前,上层的目录已经检测过,已经不可能再删,从而导致空目录删除不彻底的弊病。解决办法是:从最深层的子目录起开始删除。这就需要对目录按照层深来排序,呵呵,很有挑战性。多谢 ccwan 提醒。



尺有所短,寸有所长,学好CMD没商量。
考虑问题复杂化,解决问题简洁化。
2006-12-26 01:42
查看资料  发短消息 网志   编辑帖子  回复  引用回复
namejm
荣誉版主

batch fan


积分 5226
发帖 1737
注册 2006-3-10
来自 成都
状态 离线
『第 6 楼』:  

  以下代码能够删除当前目录下的所有空文件夹(包括子目录中的)而不会出现5楼所说的遗漏的现象,兼容含有特殊字符的路径,8楼的问题也得到了解决。请各位新建目录来测试,以免造成不必要的损失:
@echo off
:: 思路:列举所有目录(包括子目录)路径,然后,删除第一个路径最后一节上的文件夹;
::   如果能删除这个文件夹,则删除上一层文件夹;如果还能删除,则继续上一步……
::   直到当前目录为止;如果其中某一节不能删除,立即跳出,开始删除下一条路径中
::   最后一节上的文件夹……如此反复。

for /f "delims=" %%i in ('dir /ad /b /s') do call :rd_dir_empty "%%i"
goto :eof

rem ======= 删除空目录 =========
:rd_dir_empty
rd %1 2>nul||goto :eof
set dir_route=%1
for /f "delims=" %%i in (%dir_route%) do (
    set dir_route="%%~dpi"
    for /f "delims=" %%j in ('dir /ad /b "%%~dpi"')do rd "%%~dpi%%j" 2>nul||goto :eof
)
:: 把路径最后的\去掉,以便set route_deepest="%%~dpi"能取到上一层路径
if "%dir_route:~-2,1%"=="\" set dir_route="%dir_route:~1,-2%"
if /i not "%cd%"==%dir_route% call :rd_dir_empty %dir_route%
goto :eof
[ Last edited by namejm on 2006-12-26 at 01:23 PM ]

   此帖被 +19 点积分         点击查看详情   
评分人:【 ccwan 分数: +15  时间:2006-12-26 04:17
评分人:【 voiL 分数: +4  时间:2006-12-26 22:18




尺有所短,寸有所长,学好CMD没商量。
考虑问题复杂化,解决问题简洁化。
2006-12-26 04:16
查看资料  发短消息 网志   编辑帖子  回复  引用回复
ccwan
金牌会员




积分 2725
发帖 1160
注册 2006-9-23
来自 河北廊坊
状态 离线
『第 7 楼』:  

呵呵,等的就是他。



三人行,必有吾师焉。   学然后知不足,教然后知困,然后能自强也。
2006-12-26 04:18
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
voiL
中级用户





积分 384
发帖 189
注册 2005-10-19
状态 离线
『第 8 楼』:  

namejm版主的代码在我这里还存在点问题:

运行前目录:

  Quote:

E:\test\6
E:\test\123
E:\test\voil
E:\test\a\adf
E:\test\2008034
E:\test\a\tga\adsf\adffwqa
E:\test\s h\s wer\1122
E:\test\s h\s132\dfads
E:\test\s h\s wer\新建文件夹
E:\test\t\tsad

运行后剩余目录:

  Quote:

E:\test\s h\s wer\1122          [空目录]
E:\test\s h\s wer\新建文件夹    [空目录]
E:\test\t\tsad                  [空目录]



2006-12-26 05:52
查看资料  发短消息 网志   编辑帖子  回复  引用回复
namejm
荣誉版主

batch fan


积分 5226
发帖 1737
注册 2006-3-10
来自 成都
状态 离线
『第 9 楼』:  

  6楼的代码已经修正,请测试。

[ Last edited by namejm on 2006-12-25 at 06:38 PM ]



尺有所短,寸有所长,学好CMD没商量。
考虑问题复杂化,解决问题简洁化。
2006-12-26 06:22
查看资料  发短消息 网志   编辑帖子  回复  引用回复
ccwan
金牌会员




积分 2725
发帖 1160
注册 2006-9-23
来自 河北廊坊
状态 离线
『第 10 楼』:  

哈哈,多次试验没有问题。



三人行,必有吾师焉。   学然后知不足,教然后知困,然后能自强也。
2006-12-26 07:44
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
voiL
中级用户





积分 384
发帖 189
注册 2005-10-19
状态 离线
『第 11 楼』:  

namejm版主的代码果然强悍,检测了十多次,每一次的速度都很快.

清除10多个到30多个空目录,基本都是一闪就搞定了...

至于删除日期文件夹方面就留给我自己去研究研究吧(如果版主有妙方的话我也是不会抗拒滴:))...

加分加分...除此以外,想不到更好的方法报答了...呵呵...

不知2楼的代码版主有没好的解决方法???

特殊字符例如:  ()[]<>^&  等等...

里面关于检测和移动的代码,我是参考以下帖子第12楼kcdsw兄的.

怎样从外部获得多个变量来支持多文件?已解决

还有这个帖子.

[原创]无奈何签名代码略析

直接用kcdsw兄的代码确实可以移动一些带特殊符号的文件,但我修改成2楼的代码就不行了...

[ Last edited by voiL on 2006-12-26 at 10:31 PM ]

2006-12-26 22:17
查看资料  发短消息 网志   编辑帖子  回复  引用回复
namejm
荣誉版主

batch fan


积分 5226
发帖 1737
注册 2006-3-10
来自 成都
状态 离线
『第 12 楼』:  

  请把那些要删除的日期文件夹的名字列举一些出来,然后把规律说明一下,应该不难的。

  2楼的代码是想实现文件的复制吧?具体想达到什么样的目的,请用文字说明,光看代码是很容易误导人的。



尺有所短,寸有所长,学好CMD没商量。
考虑问题复杂化,解决问题简洁化。
2006-12-26 23:05
查看资料  发短消息 网志   编辑帖子  回复  引用回复
voiL
中级用户





积分 384
发帖 189
注册 2005-10-19
状态 离线
『第 13 楼』:  

呵呵...谢谢namejm版主的热心帮助...

日期的命名方式都是统一的...

YYYY-MM-DD

___________________________________________

2楼的目的也只是把数个文件拖到批处理上,然后选择目的目录,之后批处理自动把文件复制到目标目录...

这个在2楼的代码中就已经可以达到了...

问题只是在于把数个文件拖到批处理上之后,批处理怎么去处理文件名里的特殊符号...

之前我试过一些带  【()[]^&+】  等字符的文件无法正确复制...

所以就到论坛上找,找是找到了,但经自己修改后又不行了...

不知问题是出在哪里...

我把它精简成如下这样又可以处理一些例如: ()[]  等字符了,但遇到 1+1.txt  这样的名字又出错了.可问题也在于我不想要精简的,因为我的文件要备份到好几个目录的,如果做几个批处理,每个批处理只指向一个目标目录的话,又不太实际.
@echo off
color 17
mode con lines=25 cols=80
set targetdir1=n:\政府网站

:gov
cls
if not exist %targetdir1%\nul goto nodir
dir %1\. >nul 2>nul && goto nofolder
echo.
echo.
echo                ┏━━━━━━━━━━━━━━━━━━━━━━━┓
echo                ┃                                              ┃
echo                ┃正在复制文件到 〖政府网站〗 目录下,请稍候... ┃
echo                ┃                                              ┃
echo                ┗━━━━━━━━━━━━━━━━━━━━━━━┛
copy /y %1 %targetdir1% 2>nul 1>nul
if %2! == ! goto nextgov
Shift
goto gov

:nextgov
cls
echo.
echo.
echo              ┏━━━━━━━━━━━━━━━━━━━━━━━━━┓
echo              ┃                                                  ┃
echo              ┃文件已成功复制到 〖政府网站〗 目录下,3秒后退出...┃
echo              ┃                                                  ┃
echo              ┗━━━━━━━━━━━━━━━━━━━━━━━━━┛
goto end

:end
ping 1.1 -n 1 -w 3000 >nul 2>nul
exit
程序必须附带以下几个检测(不知是否就是因为有以下代码才导致程序不能正确处理特殊字符的?)

  Quote:
::来检测是否有源文件,没有则跳转到nofiles标签
for %%i in (%*) do if "!%%i" == "!" goto nofiles

::检测目标目录是否存在,不存在则跳转到nodir标签
if not exist %targetdir1%\nul goto nodir

::检测拖进来的文件之中是否有目录,如有则跳转到nofolder标签
dir %1\. >nul 2>nul && goto nofolder

[ Last edited by voiL on 2006-12-27 at 12:02 AM ]

2006-12-26 23:49
查看资料  发短消息 网志   编辑帖子  回复  引用回复
namejm
荣誉版主

batch fan


积分 5226
发帖 1737
注册 2006-3-10
来自 成都
状态 离线
『第 14 楼』:  

  要处理含特殊字符的文件名,必须把路径用引号括起来;^会被认为是转义字符,不太好处理,建议文件名中不要包含它。在使用 set /p 语句的情况下,把文件拉到CMD窗口来的时候,CMD解释器会自动给带空格的路径加上引号,其余的情况不会自动加,所以,当用 set /p 来接收输入之后,要先去掉可能存在的引号,然后再统一加上引号,就可以保证能处理含特殊字符文件名了,比如下面的演示代码:
@echo off
:begin
cls
set input=
set /p input=请输入测试文件名:
set "input=%input:"=%"
echo 你输入的文件名是:"%input%"
pause
goto begin
  至于查找日期格式的文件夹名,可以用 findstr 的正则表达式,请看如下演示代码(检测不是很严格):
@echo off
for /f "delims=" %%i in ('dir /ad /b^|findstr /b /e "[1-2][0-9][0-9][0-9]-[0-1][0-9]-[0-3][0-9]"') do echo "%%i"
pause




尺有所短,寸有所长,学好CMD没商量。
考虑问题复杂化,解决问题简洁化。
2006-12-27 00:27
查看资料  发短消息 网志   编辑帖子  回复  引用回复
namejm
荣誉版主

batch fan


积分 5226
发帖 1737
注册 2006-3-10
来自 成都
状态 离线
『第 15 楼』:  

  9527 同志太不厚道,跑到无忧光盘启动论坛去发帖子,却没在这里把他的好代码放出来。现在代他发一个更简洁的代码:
for /f "tokens=*" %a in ('dir /b /ad /s 目录路径^|sort /r') do rd "%a" /q 2>nul




尺有所短,寸有所长,学好CMD没商量。
考虑问题复杂化,解决问题简洁化。
2006-12-30 05:31
查看资料  发短消息 网志   编辑帖子  回复  引用回复
« [1] [2] »
请注意:您目前尚未注册或登录,请您注册登录以使用论坛的各项功能,例如发表和回复帖子等。


可打印版本 | 推荐给朋友 | 订阅主题 | 收藏主题



论坛跳转: