我正在寻找一种方法来删除批处理文件中超过7天的所有文件。我在网上搜索了一下,找到了一些包含数百行代码的示例,还有一些示例需要安装额外的命令行实用程序来完成任务。
在BASH中,只需几行代码就可以完成类似的工作。在Windows中,似乎可以为批处理文件做一些简单的事情。我正在寻找一个解决方案,工作在标准的Windows命令提示符,没有任何额外的实用程序。请不要使用PowerShell或Cygwin。
我正在寻找一种方法来删除批处理文件中超过7天的所有文件。我在网上搜索了一下,找到了一些包含数百行代码的示例,还有一些示例需要安装额外的命令行实用程序来完成任务。
在BASH中,只需几行代码就可以完成类似的工作。在Windows中,似乎可以为批处理文件做一些简单的事情。我正在寻找一个解决方案,工作在标准的Windows命令提示符,没有任何额外的实用程序。请不要使用PowerShell或Cygwin。
当前回答
扩展aku的回答,我看到很多人在问北卡大学的路径。简单地将unc路径映射到驱动器号将使forfiles高兴。例如,驱动器的映射和取消映射可以在批处理文件中以编程方式完成。
net use Z: /delete
net use Z: \\unc\path\to\my\folder
forfiles /p Z: /s /m *.gz /D -7 /C "cmd /c del @path"
这将删除所有扩展名为.gz且超过7天的文件。如果你想确保Z:在使用它之前没有映射到任何其他东西,你可以做一些简单的事情
net use Z: \\unc\path\to\my\folder
if %errorlevel% equ 0 (
forfiles /p Z: /s /m *.gz /D -7 /C "cmd /c del @path"
) else (
echo "Z: is already in use, please use another drive letter!"
)
其他回答
更灵活的方法是使用FileTimeFilterJS.bat:
@echo off
::::::::::::::::::::::
set "_DIR=C:\Users\npocmaka\Downloads"
set "_DAYS=-5"
::::::::::::::::::::::
for /f "tokens=* delims=" %%# in ('FileTimeFilterJS.bat "%_DIR%" -dd %_DAYS%') do (
echo deleting "%%~f#"
echo del /q /f "%%~f#"
)
该脚本将允许您使用诸如日、分、秒或小时等测量。 选择weather按创建、访问或修改时间筛选文件 列出某个日期之前或之后(或两个日期之间)的文件 选择是显示文件还是dirs(或两者都显示) 递归与否
请允许我在这条已经很有价值的线索上再做一点小小的贡献。我发现其他解决方案可能会摆脱实际的错误文本,但忽略了%ERRORLEVEL%,这表明我的应用程序失败。并且我合理地想要%ERRORLEVEL%,只要它不是“没有找到文件”错误。
一些例子:
具体地调试和消除错误:
forfiles /p "[file path...]\IDOC_ARCHIVE" /s /m *.txt /d -1 /c "cmd /c del @path" 2>&1 | findstr /V /O /C:"ERROR: No files found with the specified search criteria."2>&1 | findstr ERROR&&ECHO found error||echo found success
使用一个线性程序返回ERRORLEVEL成功或失败:
forfiles /p "[file path...]\IDOC_ARCHIVE" /s /m *.txt /d -1 /c "cmd /c del @path" 2>&1 | findstr /V /O /C:"ERROR: No files found with the specified search criteria."2>&1 | findstr ERROR&&EXIT /B 1||EXIT /B 0
在批处理文件的上下文中,在其他代码的中间使用一个线性程序来保持ERRORLEVEL为0 (ver > nul重置ERRORLEVEL):
forfiles /p "[file path...]\IDOC_ARCHIVE" /s /m *.txt /d -1 /c "cmd /c del @path" 2>&1 | findstr /V /O /C:"ERROR: No files found with the specified search criteria."2>&1 | findstr ERROR&&ECHO found error||ver > nul
对于SQL Server代理CmdExec作业步骤,我落在下面。我不知道这是否是一个错误,但该步骤中的CmdExec只识别第一行代码:
cmd /e:on /c "forfiles /p "C:\SQLADMIN\MAINTREPORTS\SQL2" /s /m *.txt /d -1 /c "cmd /c del @path" 2>&1 | findstr /V /O /C:"ERROR: No files found with the specified search criteria."2>&1 | findstr ERROR&&EXIT 1||EXIT 0"&exit %errorlevel%
扩展aku的回答,我看到很多人在问北卡大学的路径。简单地将unc路径映射到驱动器号将使forfiles高兴。例如,驱动器的映射和取消映射可以在批处理文件中以编程方式完成。
net use Z: /delete
net use Z: \\unc\path\to\my\folder
forfiles /p Z: /s /m *.gz /D -7 /C "cmd /c del @path"
这将删除所有扩展名为.gz且超过7天的文件。如果你想确保Z:在使用它之前没有映射到任何其他东西,你可以做一些简单的事情
net use Z: \\unc\path\to\my\folder
if %errorlevel% equ 0 (
forfiles /p Z: /s /m *.gz /D -7 /C "cmd /c del @path"
) else (
echo "Z: is already in use, please use another drive letter!"
)
看看我对类似问题的回答:
REM del_old.bat
REM usage: del_old MM-DD-YYY
for /f "tokens=*" %%a IN ('xcopy *.* /d:%1 /L /I null') do if exist %%~nxa echo %%~nxa >> FILES_TO_KEEP.TXT
for /f "tokens=*" %%a IN ('xcopy *.* /L /I /EXCLUDE:FILES_TO_KEEP.TXT null') do if exist "%%~nxa" del "%%~nxa"
这将删除比给定日期更早的文件。我相信它可以被修改为从当前日期往回走7天。
更新:我注意到HerbCSO已经改进了上面的脚本。我建议改用他的版本。
我认为e.James的答案很好,因为它适用于早于Windows 2000 SP4(可能更早)的未修改版本的Windows,但它需要写入外部文件。下面是一个修改后的版本,在保持兼容性的同时不创建外部文本文件:
REM del_old.cmd
REM usage: del_old MM-DD-YYYY
setlocal enabledelayedexpansion
for /f "tokens=*" %%a IN ('xcopy *.* /d:%1 /L /I null') do @if exist "%%~nxa" set "excludefiles=!excludefiles!;;%%~nxa;;"
for /f "tokens=*" %%a IN ('dir /b') do @(@echo "%excludefiles%"|FINDSTR /C:";;%%a;;">nul || if exist "%%~nxa" DEL /F /Q "%%a">nul 2>&1)
为了忠于最初的问题,如果你用天数作为参数调用它,它在一个脚本中为你做了所有的数学运算:
REM del_old_compute.cmd
REM usage: del_old_compute N
setlocal enabledelayedexpansion
set /a days=%1&set cur_y=%DATE:~10,4%&set cur_m=%DATE:~4,2%&set cur_d=%DATE:~7,2%
for /f "tokens=1 delims==" %%a in ('set cur_') do if "!%%a:~0,1!"=="0" set /a %%a=!%%a:~1,1!+0
set mo_2=28&set /a leapyear=cur_y*10/4
if %leapyear:~-1% equ 0 set mo_2=29
set mo_1=31&set mo_3=31&set mo_4=30&set mo_5=31
set mo_6=30&set mo_7=31&set mo_8=31&set mo_9=30
set mo_10=31&set mo_11=30&set mo_12=31
set /a past_y=(days/365)
set /a monthdays=days-((past_y*365)+((past_y/4)*1))&&set /a past_y=cur_y-past_y&set months=0
:setmonth
set /a minusmonth=(cur_m-1)-months
if %minusmonth% leq 0 set /a minusmonth+=12
set /a checkdays=(mo_%minusmonth%)
if %monthdays% geq %checkdays% set /a months+=1&set /a monthdays-=checkdays&goto :setmonth
set /a past_m=cur_m-months
set /a lastmonth=cur_m-1
if %lastmonth% leq 0 set /a lastmonth+=12
set /a lastmonth=mo_%lastmonth%
set /a past_d=cur_d-monthdays&set adddays=::
if %past_d% leq 0 (set /a past_m-=1&set adddays=)
if %past_m% leq 0 (set /a past_m+=12&set /a past_y-=1)
set mo_2=28&set /a leapyear=past_y*10/4
if %leapyear:~-1% equ 0 set mo_2=29
%adddays%set /a past_d+=mo_%past_m%
set d=%past_m%-%past_d%-%past_y%
for /f "tokens=*" %%a IN ('xcopy *.* /d:%d% /L /I null') do @if exist "%%~nxa" set "excludefiles=!excludefiles!;;%%~nxa;;"
for /f "tokens=*" %%a IN ('dir /b') do @(@echo "%excludefiles%"|FINDSTR /C:";;%%a;;">nul || if exist "%%~nxa" DEL /F /Q "%%a">nul 2>&1)
注意:上面的代码考虑了闰年,以及每个月的确切天数。唯一的最大值是从0/0/0开始的总天数(之后返回负年份)。
注意:数学只是单向的;它不能从负输入中正确地获得未来的日期(它会尝试,但可能会超过本月的最后一天)。