标题: [文件操作] 求教批处理只保留指定文件夹和文件 [打印本页]
作者: smatenchen 时间: 2021-5-22 15:36 标题: 求教批处理只保留指定文件夹和文件
1
最近想学点批处·理技巧,现遇到了难题,特来求教!
2
问题
d:\1\ 下有好多文件和文件夹。
只保留以111和222为开头的文件夹,以333和444为开头的文件,
以及所有.ini和.exe文件。
要求
要同时满足上述所有条件。
弃用move命令。
最好别用>1.txt这样的命令。
应该是得用set, for, if, rd, del等命令,
想了好久,未得解法。
现来求教,求指点。
多谢!
作者: 1152 时间: 2021-5-22 17:25
标题太乱了!
作者: smatenchen 时间: 2021-5-22 19:17
没人懂得如何解法吗?
作者: qixiaobin0715 时间: 2021-5-22 19:51
你提的条件太多了,一次性解决不是不行,还不如分开实现。一次性解决可用:- for /f ... ('dir /b') do (
- 这里用if进行判断
- ...
- )
- pause
复制代码
作者: qixiaobin0715 时间: 2021-5-22 20:04
本帖最后由 qixiaobin0715 于 2021-5-23 08:48 编辑
回复 1# smatenchen
文件和文件夹分别处理,未测试,del/rd慎用:- @echo off
- for /f "delims=" %%a in ('dir /b /ad ^|findstr /vb "111 222"') do rd %%a
- for /f "delims=" %%b in ('dir /b /a-d ^|findstr /ev ".ini .exe .bat"^|findstr /bv "333 444"') do del %%b
- pause
复制代码
作者: xp3000 时间: 2021-5-22 20:05
本帖最后由 xp3000 于 2021-5-23 06:45 编辑
- @cd /d d:\1\
-
- @echo off & setlocal EnableDelayedExpansion
- for /f "tokens=*" %%i in ('dir /a:d /b *') do (echo 搜索目录"%%i"&echo.
- for /f "delims=" %%j in ('echo %%i^| findstr /i /v "^111 ^222"') do echo 删除非匹配目录"%%j"&echo.&rd "%%j" /s /q
- for /f "delims=" %%k in ('echo %%i^| findstr /i /r /x "^111.* ^222.*"') do (echo 符合要求,即将切换.......
- pushd %%k&echo 切换目录"%%k"
- for /f "delims=" %%l in ('dir /b/a-d/on *.*^| findstr /i /v "^333 ^444"^| findstr /i /v "exe$ ini$"') do (
- echo 搜索到非匹配文件,删除"%%l" & del /f /s /q "%%l"
- )
- popd&echo.退出目录"%%k"&echo.
- rd "%%k" 2>nul&echo 如果"%%k"为空文件夹将删除
- )
- )
- )
- pause
复制代码
作者: smatenchen 时间: 2021-5-22 22:16
回复 6# xp3000
我是初学者,哪里看得懂这么复杂的命令!有空的话,请您详解这些命令的含义。其中!pushd什么的,我根本看不懂啊!
作者: smatenchen 时间: 2021-5-22 22:22
回复 5# qixiaobin0715
我是初学者,看不懂啊!您可以详细说说吗?
作者: smatenchen 时间: 2021-5-22 22:29
回复 2# 1152
问题有解吗?
作者: smatenchen 时间: 2021-5-22 22:31
回复 4# qixiaobin0715
应该是吧!
我是初学者,不知如何解,特来求教啊!
作者: smatenchen 时间: 2021-5-22 22:36
回复 5# qixiaobin0715
不怕!
我专门用来测试的,删了也没事。
作者: newswan 时间: 2021-5-23 03:44
- for /f "delims=" %%a in ('dir /b /ad ^|findstr /r /v "<111 <222"') do (
- rd /s %%a
- )
- for /f "delims=" %%a in ('dir /b /a-d ^|findstr /r /v "<333 <444 .ini> .exe>"') do (
- del %%a
- )
复制代码
作者: xp3000 时间: 2021-5-23 06:46
回复 7# smatenchen
添加了注释,也清晰了,昨天比较混乱
作者: qixiaobin0715 时间: 2021-5-23 07:52
回复 12# newswan
表达单词的起始位置和结束位置,少了一个反斜杠。
还是用^和$要严谨些,如果文件名是“abc 333.txt” 哪?
作者: qixiaobin0715 时间: 2021-5-23 08:11
回复 8# smatenchen
具体可以看看http://bbs.bathome.net/thread-14682-1-1.html
作者: smatenchen 时间: 2021-5-23 08:39
回复 smatenchen
文件和文件夹分别处理,未测试,del/rd慎用:
qixiaobin0715 发表于 2021-5-22 20:04
完全无效啊!
屏幕一闪,连pause命令都没执行就退出了。
最后还把批处理文件本身给删了!
您这也太不靠谱了吧?
作者: smatenchen 时间: 2021-5-23 08:44
xp3000 发表于 2021-5-22 20:05
昨天的无效啊!
还出现了乱码!
这个题有这么难吗?
今天的我再试试。
非常感谢您!您这么的热心!
受教了!学习了!
作者: smatenchen 时间: 2021-5-23 08:47
回复 5# qixiaobin0715
完全无效啊!
屏幕一闪,连pause命令都没执行就退出了。
最后还把批处理文件本身给删了!
您再改改吧!
作者: smatenchen 时间: 2021-5-23 08:47
回复 6# xp3000
昨天的无效啊!
还出现了乱码!
这个题有这么难吗?
今天的我再试试。
非常感谢您!您这么的热心!
受教了!学习了!
作者: qixiaobin0715 时间: 2021-5-23 09:29
本帖最后由 qixiaobin0715 于 2021-5-23 10:09 编辑
回复 16# smatenchen
在代码上面已经做过说明了,未经测试。已修改,未测试。
作者: qixiaobin0715 时间: 2021-5-23 09:34
本帖最后由 qixiaobin0715 于 2021-5-23 10:08 编辑
findstr看不明白,用if吧,这样应当看得懂吧,未测试:- @echo off
- setlocal enabledelayedexpansion
- for /f "delims=" %%a in ('dir /b') do (
- set "str=%%a"
- set "str1=!str:~,3!"
- set "str2=!str:~-3!"
- if "%%~xa"=="" (
- if not !str1!==111 (
- if not !str1!==222 rd "%%a"
- )
- )
-
- if not "%%~xa"=="" (
- if not !str2!==ini (
- if not !str2!==exe (
- if not !str2!==bat (
- if not !str1!==333 (
- if not !str1!==444 del %%a
- )
- )
- )
- )
- )
-
- )
- pause
复制代码
作者: smatenchen 时间: 2021-5-23 10:20
回复 20# qixiaobin0715
好的!我再试试吧!谢谢您!
作者: smatenchen 时间: 2021-5-23 10:33
回复 21# qixiaobin0715
非常感谢您的热心!
受教了!学习了!
作者: xp3000 时间: 2021-5-23 14:13
只要乱码,必定是你没默认ANSI编码新建文本改名为BAT,而是把其他非ANSI文件改的
要是还不行我只有删除了,两个我都试了可行
作者: smatenchen 时间: 2021-5-23 14:16
只要乱码,必定是你没默认ANSI编码新建文本改名为BAT,而是把其他非ANSI文件改的
xp3000 发表于 2021-5-23 13:48
我把批处理内容保存为uft-8格式的文件了。
原来还有这种事啊!
记事本默认保存格式就是uft-8格式,所以没改它就直接保存了。
学习了!多谢了!
作者: smatenchen 时间: 2021-5-23 14:29
回复 24# xp3000
我注意到您在批处理中用dir 命令时,没引用文件的绝对路径,
使用了默认的当前目录环境,
这岂不是非得把批处理文件放在要处理对象所在的目录里不可吗?
我若是以管理员权限运行该批处理文件时,那要如何是好呢?
作者: xp3000 时间: 2021-5-23 14:45
cd /d 必定切换目录
作者: smatenchen 时间: 2021-5-23 18:41
回复 21# qixiaobin0715
您好!
if "%%~xa"=="" (
这个语句是何意?
%%~xa
这是什么变量?
怎么还带上了~x,是何意?
您好像没先定义出%%~xa这个变量吧?
没看懂,请您解说一下吧!
多谢!
作者: smatenchen 时间: 2021-5-23 18:44
回复 27# xp3000
多谢!
没仔细看,漏看了您的这个语句。
受教了!您费心了!
作者: smatenchen 时间: 2021-5-23 19:07
回复 5# qixiaobin0715
您好!
('dir /b /ad ^|findstr /vb "111 222"')
这里用^| 是何意?
干嘛要转义?直接用管道 | 接上不行吗?
多谢!
作者: smatenchen 时间: 2021-5-23 21:01
回复 6# xp3000
您好!
pushd popd
这两个起什么作用?
多谢!
作者: smatenchen 时间: 2021-5-23 21:05
回复 6# xp3000
您好!
exe$ ini$
这个是何意?
"^111 ^222"
这是何意?转义?
这是什么用法?
多谢!
作者: smatenchen 时间: 2021-5-23 21:06
回复 6# xp3000
您好!
2>nul
这是什么用法?
多谢!
作者: qixiaobin0715 时间: 2021-5-23 21:29
回复 28# smatenchen
变量参数%%a增强
扩充到一个文件扩展名:%%~xa(.txt/.doc ...等)
作者: qixiaobin0715 时间: 2021-5-23 21:33
回复 30# smatenchen
在引号内需转义
作者: newswan 时间: 2021-5-23 23:33
回复 14# qixiaobin0715
对,^ $ 更严谨些
作者: smatenchen 时间: 2022-8-14 18:16
回复 6# xp3000 Batcher qixiaobin0715
{
@cd /d d:\1\
@echo off & setlocal EnableDelayedExpansion
for /f "tokens=*" %%i in ('dir /a:d /b *') do (echo 搜索目录"%%i"&echo.
for /f "delims=" %%j in ('echo %%i^| findstr /i /v "^111 ^222"') do echo 删除非匹配目录"%%j"&echo.&rd "%%j" /s /q
for /f "delims=" %%k in ('echo %%i^| findstr /i /r /x "^111.* ^222.*"') do (echo 符合要求,即将切换.......
pushd %%k&echo 切换目录"%%k"
for /f "delims=" %%l in ('dir /b/a-d/on *.*^| findstr /i /v "^333 ^444"^| findstr /i /v "exe$ ini$"') do (
echo 搜索到非匹配文件,删除"%%l" & del /f /s /q "%%l"
)
popd&echo.退出目录"%%k"&echo.
rd "%%k" 2>nul&echo 如果"%%k"为空文件夹将删除
)
)
)
pause
}
1,
非常感谢!
2,
以上你写的代码你自己是否测试过呢?
3,
套了这么多层循环,运行效率,速度,肯定不高,将会有一长串运行结果啊!
4,
其运行逻辑,并不够清晰,代码庞杂,纠错时费力。
5,
其运行时会一闪而过,代码里的提示词就显得是多余的了。
6,
与第5楼的代码,实在是没法相提并论。
{
@echo off
for /f "delims=" %%a in ('dir /b /ad ^|findstr /vb "111 222"') do rd %%a
for /f "delims=" %%b in ('dir /b /a-d ^|findstr /ev ".ini .exe .bat"^|findstr /bv "333 444"') do del %%b
pause
}
7,
简单非常重要啊!你把原本简单的搞到极度复杂了!唉!
作者: smatenchen 时间: 2022-8-14 18:24
回复 12# newswan
1,
非常感谢!
2,
你写的代码,其中的<,>,应该是\<xyz,xyz\>。
作者: hfxiang 时间: 2022-8-16 19:46
本帖最后由 hfxiang 于 2022-8-16 20:04 编辑
- @echo off
- @rem 只保留以 111 和 222 为开头的文件夹,以 333 和 444 为开头的文件,以及所有.ini 和.exe 文件。
- @setlocal enableDelayedExpansion
-
- for /f "delims==" %%a in ('set _retain_ 2^>nul') do set "%%a="
- set "_retain_Folder_111=True"
- set "_retain_Folder_222=True"
- set "_retain_File_333=True"
- set "_retain_File_444=True"
- set "_retain_File_.ini=True"
- set "_retain_File_.exe=True"
-
- for /r %%a in (.,*) do (
- set "Dir_a=%%~aa"
- set "Dir_x=%%~xa"
- set "Dir_n=%%~na"
- set "Dir_n=!Dir_n:~0,3!"
- if /i not "[%cd%]"=="[%%~fa]" if /i not "[%~f0]"=="[%%~fa]" if defined Dir_a if "[!Dir_a:~0,1!]"=="[d]" (
- if not defined _retain_Folder_!Dir_n! rd /q/s "%%~fa"
- ) else (
- set "_retain_File_T="
- if defined _retain_File_!Dir_n! set "_retain_File_T=True"
- if defined _retain_File_!Dir_x! set "_retain_File_T=True"
- if not defined _retain_File_T del/f/s/q "%%~fa"
- )
- )
-
- endlocal
- echo;&pause
- exit /b
复制代码
作者: qixiaobin0715 时间: 2022-8-17 08:54
回复 37# smatenchen
有时 简洁≠效率高。
5楼代码在循环体中使用了管道命令,效率就会降低。从楼上代码中受到启示,弃用管道命令,全部使用判断语句,这样效率可能要高一些:- @echo off
- setlocal enabledelayed
- for %%i in (333 444 .ini .exe .bat) do set _%%i=true
- for %%i in (111 222) do set #%%i=true
- for /f "delims=" %%i in ('dir /b /ad') do (
- set str=%%i
- if not defined #!str:~,3! rd /q /s "%%i"
- )
- for /f "delims=" %%i in ('dir /b /a-d') do (
- set str=%%i
- if not defined _%%~xi (
- if not defined _!str:~,3! del "%%i"
- )
- )
- pause
复制代码
作者: hfxiang 时间: 2022-8-17 09:11
回复 40# qixiaobin0715
学习了一下,虽然没做测试,感觉这些代码对文件夹的处置部分可行,对文件的处置部分有可能工作起来不太顺畅。
作者: smatenchen 时间: 2022-8-18 11:27
回复 40# qixiaobin0715
回复 39# hfxiang
{
@echo off
setlocal enabledelayed
for %%i in (333 444 .ini .exe .bat) do set _%%i=true
for %%i in (111 222) do set #%%i=true
for /f "delims=" %%i in ('dir /b /ad') do (
set str=%%i
if not defined #!str:~,3! rd /q /s "%%i"
)
for /f "delims=" %%i in ('dir /b /a-d') do (
set str=%%i
if not defined _%%~xi (
if not defined _!str:~,3! del "%%i"
)
)
pause
}
1,
非常感谢!
2,
二位的的解题思路,挺广阔啊!
3,
你写的代码里,其中do set _%%i=true,do set #%%i=true里的,=true改成=0或1或false或aa或123,应该都是可以的吧?
作者: hfxiang 时间: 2022-8-18 13:00
回复 42# smatenchen
用什么都一样,这个只是表示标识的存在与否,更直白地说是这个标识“有值”和“无值”的问题
作者: smatenchen 时间: 2022-8-18 15:12
回复 43# hfxiang
1,
非常感谢!
2,
鄙人分析代码时,感觉=true只是起一个标记的意义。
现在,你把它证实了。
3,
说实在的,把解法代码写成这些做判断的代码会比写成用 | 连接的代码,其运行时会更有效率吗?
作者: hfxiang 时间: 2022-8-18 15:33
回复 44# smatenchen
本人认为更高效,但实际情况你可以用大量一点的数据来测试对,有时还是相信自己的测试比较好!
作者: qixiaobin0715 时间: 2022-8-18 16:29
效率是个复杂的问题:
1.单独使用管道、单独使用命令及单独使用for循环,在效率上都没有问题,组合起来就有可能影响效率;
2.实际上40楼后2个for循环与命令dir连用也会影响效率;
40楼代码可以这样改写:- @echo off
- setlocal enabledelayed
- for %%i in (333 444 .ini .exe .bat) do set _%%i=true
- for %%i in (111 222) do set #%%i=true
- for /d %%i in (*) do (
- set str=%%i
- if not defined #!str:~,3! rd /q /s "%%i"
- )
- for %%i in (*) do (
- set str=%%i
- if not defined _%%~xi (
- if not defined _!str:~,3! del "%%i"
- )
- )
- pause
复制代码
作者: smatenchen 时间: 2022-8-18 17:50
回复 45# hfxiang
作者: smatenchen 时间: 2022-8-18 23:33
本帖最后由 smatenchen 于 2022-8-19 08:51 编辑
回复 39# hfxiang
回复 40# qixiaobin0715
回复 3# Batcher
{
@echo off
@rem 只保留以 111 和 222 为开头的文件夹,以 333 和 444 为开头的文件,以及所有.ini 和.exe 文件。
@setlocal enableDelayedExpansion
for /f "delims==" %%a in ('set _retain_ 2^>nul') do set "%%a="
set "_retain_Folder_111=True"
set "_retain_Folder_222=True"
set "_retain_File_333=True"
set "_retain_File_444=True"
set "_retain_File_.ini=True"
set "_retain_File_.exe=True"
for /r %%a in (.,*) do (
set "Dir_a=%%~aa"
set "Dir_x=%%~xa"
set "Dir_n=%%~na"
set "Dir_n=!Dir_n:~0,3!"
if /i not "[%cd%]"=="[%%~fa]" if /i not "[%~f0]"=="[%%~fa]" if defined Dir_a if "[!Dir_a:~0,1!]"=="[d]" (
if not defined _retain_Folder_!Dir_n! rd /q/s "%%~fa"
) else (
set "_retain_File_T="
if defined _retain_File_!Dir_n! set "_retain_File_T=True"
if defined _retain_File_!Dir_x! set "_retain_File_T=True"
if not defined _retain_File_T del/f/s/q "%%~fa"
)
)
endlocal
echo;&pause
exit /b
}
1,
非常感谢!
2,
你自己测试过你写的这些代码,验证过它有效吗?
3,
set "Dir_a=%%~aa"
这句应该是错的吧?
应该写成 set "Dir_a=%%~da" 或 set "Dir_d=%%~da" 吗?
若是你写错了,那后面引用它时,也该都错了。
4,
for /r %%a in (.,*) do (
这句其中的(.,*),是何意呢?.,*这代表什么呢?是指当前目录下文件名开头处含有.,这两个字符的任何文件吗?
5,
if /i not "[%cd%]"=="[%%~fa]"
这句也不对吧?这个方括号[]起什么作用呢?
当前目录,不等于,%%a的完整路径名?这本来就是不等于的吧?又何必再用if去判断一下呢?
6,
if defined Dir_a
前面不是已经做了定义吗?还要再用if去做判断吗?喏,set "Dir_a=%%~aa" 。
7,
if "[!Dir_a:~0,1!]"=="[d]"
前面的set "Dir_a=%%~aa",应该是定义错了,应该是set "Dir_d=%%~da",
那后面就应该写成if "[!Dir_d:~0,1!]"=="[d]"吧?
8,
还有,
对于有隐藏属性的文件及文件夹,怎么处理呢?
不用dir /a /b命令,它们就是隐形的,for命令本身枚举不了它们。
哈哈!你们考虑过这一问题吗?
9,
另外!
Batcher,
之前,鄙人在查看qixiaobin0715的回复时,点了一下上方蓝色提示条的关闭按钮。
之后,当qixiaobin0715再回复鄙人时,论坛就不再发消息通知鄙人了。
坛主,有办法恢复通知功能吗?
10,
此外!
若需要在for %%a in () ,中的()里是多条带空格的字符串时,用""把带空格的字符串括起来,
但运行时%%a的值也是带了""号的。
如何天然地使它去掉""号,而不是去使用%%~a才办到呢?
若情况变为,需要在for /f %%a in () ,中的()里是多条带空格的字符串时,应该写成怎样的代码呢?
难道是要像Batcher之前那样,在()里套for循环命令,或者是把多条带空格的字符串写入某个文本文件1.text里吗?
作者: hfxiang 时间: 2022-8-19 07:43
回复 48# smatenchen
你自行测试一下不就知道对错了????
作者: smatenchen 时间: 2022-8-19 08:48
回复 46# qixiaobin0715
{
@echo off
setlocal enabledelayed
for %%i in (333 444 .ini .exe .bat) do set _%%i=true
for %%i in (111 222) do set #%%i=true
for /d %%i in (*) do (
set str=%%i
if not defined #!str:~,3! rd /q /s "%%i"
)
for %%i in (*) do (
set str=%%i
if not defined _%%~xi (
if not defined _!str:~,3! del "%%i"
)
)
pause
}
1,
非常感谢!
2,
把代码写成这样,似乎是在倒着走啊!
3,
不用dir /a /b命令,隐藏文件处理得了吗?
4,
本已把解法处理得很好了,却非要舍易求难,鄙人只好对此说佩服了!
作者: smatenchen 时间: 2022-8-19 14:35
回复 50# qixiaobin0715
回复 49# hfxiang
回复 3# Batcher
回复 48# smatenchen
1.”鄙人“是显得有学问还是谦虚的说法?总之我觉得在这里是不合时宜的。
是谦虚的说法。我刚学批处理,有很多不懂的,故用鄙人自称,是不敢托大。既然先师不喜欢,那就用我自称。
2.代码没有万能的,只能是就事论事,不可能考虑所有特殊性,比如特殊字符、效率、文件及文件夹的属性。
发问时,我就想着要一并处理隐藏文件,所以,我会在意有没有做到这一点。
3.上面代码只是单从效率角度来说的。
仅是用户普通文件操作,非服务器大数据处理操作,故代码简单才是首选。
4.别人帮你写代码,不管是否经过测试,总体来说测试这件事是你的本分,而不能强求写代码的人去测试。
这话就没道理了!大家都该对自己做的事去负责,直到底呀!正所谓,送佛送到西,帮人帮到底嘛!
5.最好自己测试后,才能对代码提出问题,不能看到代码就说这句不对,那句不行。
敏而好学,学而多思,不知多问,不亦悦乎?哈哈!我是来学习,能讨论就加入讨论的呀!
另外,一般来说,大家都能看的清,字体不必要太大呀。
字体大点,主要是想方便我,而非其它,要不然我看着费眼力。
作者: smatenchen 时间: 2022-8-19 14:56
本帖最后由 smatenchen 于 2022-8-19 15:01 编辑
回复 52# qixiaobin0715
回复 49# hfxiang
回复 3# Batcher
1,
非常感谢!
2,
4,
for /r %%a in (.,*) do (
这句其中的(.,*),是何意呢?.,*这代表什么呢?是指当前目录下文件名开头处含有.,这两个字符的任何文件吗?
你看懂了其中的(.,*)吗?.,*这是什么含义呢?
你看懂了,请帮忙解说一下吧?我至此,还是没弄懂呀!
3,
5,
if /i not "[%cd%]"=="[%%~fa]"
这句也不对吧?这个方括号[]起什么作用呢?
当前目录,不等于,%%a的完整路径名?这本来就是不等于的吧?又何必再用if去判断一下呢?
这里的方括号[],又起什么作用呢?
4,
拢共有那么多条发问,干嘛没有逐条解答呢?先师们解答了所有发问,我不就又提高了一小步吗?
故,还望不吝赐教于我,一个初入门,后学者呀!
拜谢!
作者: smatenchen 时间: 2022-8-19 15:00
回复 54# qixiaobin0715
:'(
作者: qixiaobin0715 时间: 2022-8-19 15:29
本帖最后由 qixiaobin0715 于 2022-8-19 15:34 编辑
for /r %%a in (.,*) do(还是那句话,试试即知)
不必研究这个了。我认为是为了在一个for循环里同时得到当前文件夹下的所有文件及文件夹(包括子文件夹和其中的文件),这种用法是有缺陷的,后续处理麻烦。推荐使用:- for /f "delims=" %%a in ('dir /b /s') do ...
复制代码
作者: smatenchen 时间: 2022-8-19 21:49
本帖最后由 smatenchen 于 2022-8-19 21:54 编辑
回复 57# qixiaobin0715
回复 49# hfxiang
回复 3# Batcher
1,
非常感谢!
2,
多般猜测不如测试一下。
3,
(.,*),其中.,*是指.和*,,起分隔作用,相当于空格,是或的意思。
但是,用.是表示把字符命令下某个目录下的1个空目录列举出来的意思。
4,
没错,这种用法会造成后面操作上的麻烦,实不可取也,适合作为一种解法思路去做参考。
5,
还是那句话,微软的东西真的很烂!
这个for命令,就设计得很烂,很不规范,不一致,功能上很残缺!
作者: smatenchen 时间: 2022-8-21 09:23
回复 59# qixiaobin0715
欢迎光临 批处理之家 (http://www.bathome.net/) |
Powered by Discuz! 7.2 |