删除某文件夹下五天以前的文件的批处理脚本的疑惑

时间:2021-03-24 23:08:07
问题一:
这几天在社区里得到搞人指点,获得一段删除某文件夹下五天以前的文件的批处理脚本,脚本如下:
@echo off
echo dt=date()-5>%temp%\tmp.vbs
echo s=year(dt) ^& "-" ^& right("0" ^& month(dt),2) ^& "-" ^&  right("0" ^& day(dt),2)>>%temp%\tmp.vbs
echo wscript.echo s>>%temp%\tmp.vbs
for /f "delims=x" %%i in ('cscript /nologo %temp%\tmp.vbs') do @set ref=%%i
for /f "tokens=1,2,3*" %%i in ('dir /tc d:\xtmp\tmp\*.txt^|find ":"^|find "-"') do (
if %%i LSS %ref% del /f d:\xtmp\tmp\%%l

)
这段脚本确实有效,可以删除相应的文件,但是我建立的文本文件如果是以中文命名的,却不能删除,很奇怪。


问题二:
后来,我把脚本修改为:
@echo off
echo dt=date()-5>%temp%\tmp.vbs
echo s=year(dt) ^& "-" ^& right("0" ^& month(dt),2) ^& "-" ^&  right("0" ^& day(dt),2)>>%temp%\tmp.vbs
echo wscript.echo s>>%temp%\tmp.vbs
for /f "delims=x" %%i in ('cscript /nologo %temp%\tmp.vbs') do @set ref=%%i
for /f "tokens=1,2,3*" %%i in ('dir /tc d:\xtmp\tmp\*.*^|find ":"^|find "-"') do (
if %%i LSS %ref% del /f d:\xtmp\tmp\%%l

)
跟原来的不同之处是我不指定文件类型,针对所有的文件类型,那么运行批处理脚本的时候,会弹出提示框:d:\xtmp\tmp\*, 是否确认 (Y/N) ?
这个时候我输入:Y,那么这个路径下面所有的文件全部删除(时间不起作用),包括中文命名的文件也可以删除,不满足我的要求的是:1、时间不起作用了 2、需要交互式输入Y或者N .

问题三、
我把脚本修改为:
@echo off
echo dt=date()-1>%temp%\tmp.vbs
echo s=year(dt) ^& "-" ^& right("0" ^& month(dt),2) ^& "-" ^&  right("0" ^& day(dt),2)>>%temp%\tmp.vbs
echo wscript.echo s>>%temp%\tmp.vbs
for /f "delims=x" %%i in ('cscript /nologo %temp%\tmp.vbs') do @set ref=%%i
for /f "tokens=1,2,3*" %%i in ('dir /tc g:\hqz\*.*^|find ":"^|find "-"') do (
if %%i LSS %ref% del /f g:\hqz\*.*%%l

)
改动之处是最后一行的路径后面加上了*.*,运行之后,不会谈出d:\xtmp\tmp\*, 是否确认 (Y/N) ?
不需要人工交互,但是时间也不起作用,这个路径下面的文件全部被删除了。

针对上述疑惑,请高手指点?

12 个解决方案

#1


呵,有点麻烦哦,建议使用Forfiles.exe这个命令,在2003下可以找到,在2000下一样适用

Forfiles /? 查看帮助

D:>forfiles /?

FORFILES [/P pathname] [/M searchmask] [/S]
         [/C command] [/D [+ | -] {yyyy-MM-dd | dd}]

描述:
    选择一个文件(或一组文件)并在那个文件上
    执行一个命令。这有助于批处理作业。

参数列表:
    /P    pathname      表示开始搜索的路径。默认文件夹是当前工作的
                        目录 (.)。

    /M    searchmask    根据搜索掩码搜索文件。默认搜索掩码是 '*'。

    /S                  指导 forfiles 递归到子目录。像 "DIR /S"。

    /C    command       表示为每个文件执行的命令。命令字符串应该
                        用双引号括起来。

                        默认命令是 "cmd /c echo @file"。下列变量
                        可以用在命令字符串中:
                        @file    - 返回文件名。
                        @fname   - 返回不带扩展名的文件名。
                        @ext     - 只返回文件的扩展。
                        @path    - 返回文件的完整路径。
                        @relpath - 返回文件的相对路径。
                        @isdir   - 如果文件类型是目录,返回 "TRUE";
                                   如果是文件,返回 "FALSE"。
                        @fsize   - 以字节为单位返回文件大小。
                        @fdate   - 返回文件上一次修改的日期。
                        @ftime   - 返回文件上一次修改的时间。

                        要在命令行包括特殊字符,字符请以 0xHH
                        形式使用十六进制代码(例如,0x09 为 tab)。
                        内部 CMD.exe 命令前面应以 "cmd /c" 开始。

    /D    date          选择文件,其上一次修改日期大于或等于 (+),
                        或者小于或等于 (-) 用 "yyyy-MM-dd" 格式指定的日期;
                        或选择文件,其上一次修改日期大于或等于 (+)
                        当前日期加 "dd" 天,或者小于或等于 (-) 当前
                        日期减 "dd" 天。有效的 "dd" 天数可以是
                        0 - 32768 范围内的任何数字。如果没有指定,
                        "+" 被当作默认符号。

    /?                  显示帮助消息。

例如:
    FORFILES /?
    FORFILES
    FORFILES /P C:\WINDOWS /S /M DNS*.*
    FORFILES /S /M *.txt /C "cmd /c type @file | more"
    FORFILES /P C:\ /S /M *.bat
    FORFILES /D -30 /M *.exe
             /C "cmd /c echo @path 0x09 在 30 前就被更改。"
    FORFILES /D 2001-01-01
             /C "cmd /c echo @fname 在 2001年1月1日就是新的。"
    FORFILES /D +2006-11-15 /C "cmd /c echo @fname 今天是新的。"
    FORFILES /M *.exe /D +1
    FORFILES /S /M *.doc /C "cmd /c echo @fsize"
    FORFILES /M *.txt /C "cmd /c if @isdir==FALSE notepad.exe @file"

#2


谢谢,不过我更希望得到的是一个脚本,也就是一个bat文件,呵呵:)
在计划任务中自动运行的,因为现在很多软件的日志很多,我想自动删除。

#3


http://www.secure-code.com/PermaLink,guid,4b1ac99b-236a-492a-8126-6b080d788337.aspx
删除某个目录下预定义天数以前的文件的脚本 


if any question, please send me a PM.

#4


我参照网址提供的,写了一段删除一天以前的文件:
<?xml version="1.0" encoding="gb2312" ?>
<?job error="true" debug="false"?>

<package id="RemoveFilesByDate">

  <job id="Main">
    <runtime>
        <description>
          FileName: RemoveFilesByDate.wsf
          这个脚本删除预定义天数以前的文件.

          Version: 1.0
          Created: icuc88@hotmail.com
          Last Modify: Feb 18th, 2004
          All right reserved.

        </description>
        <named
          name="Driver"
          helpstring="G:"
          type="string"
          required="true"
        />
        <named
          name="Path"
          helpstring="\hqz"
          type="string"
          required="true"
        />
        <named
          name="OlderBy"
          helpstring="1"
          type="string"
          required="false"
        /> 
        <example>
        Example:
          1. 删除3天以前的文件
          RemoveFilesByDate.wsf /Driver:C: /Path:\\test\\

          2. 删除5天以前的文件
          RemoveFilesByDate.wsf /Driver:C: /Path:\\test\\ /OlderBy:5
        </example>
    </runtime>

    <script language="VBScript">
    <![CDATA[
    
      Option Explicit
      On Error Resume Next

      If WScript.Arguments.Count < 2 Then
         WScript.Arguments.ShowUsage
         WScript.Quit
      Else
         ' 从指定的磁盘目录上面查找符合条件的文件
         Dim strComputer
         Dim objWMIService
         Dim colFiles
         Dim objFSO
         strComputer = "." '在本地计算机上执行脚本
         Set objWMIService = GetObject("winmgmts:" _
           & "{impersonationLevel=impersonate}!\\" _
           & strComputer & "\root\cimv2")
         Dim WMISql
         WMISql = "Select * from CIM_DataFile where Path = '" _
           & WScript.Arguments.Named.Item("Path") & "' AND Drive= '" _
           & WScript.Arguments.Named.Item("Driver") & "'" 

         Set colFiles = objWMIService.ExecQuery(WMISql)
         
         ' 删除满足条件的文件
         ' 该脚本指搜索当前路径下面的文件,不搜索子目录
         Set objFSO = CreateObject("Scripting.FileSystemObject")
         
         Dim strWMIDate
         Dim ODate
         Dim OlderBy
         Dim objFile
         For Each objFile in colFiles
           strWMIDate = objFile.CreationDate
           ODate = WMIDateStringToDate(strWMIDate)
           If WScript.Arguments.Named.Item("OlderBy") <> "" Then
             OlderBy = CInt(WScript.Arguments.Named.Item("OlderBy"))
           Else
             OlderBy = 3
           End If
           If (Date - OlderBy) >= ODate Then
             objFSO.DeleteFile(objFile.Name)       
           End If
         Next
      End If

      Function WMIDateStringToDate(dtmInstallDate) '转换WMI格式的日期类型到DateTime类型
        WMIDateStringToDate = CDate(Mid(dtmInstallDate, 5, 2) & "/" & _
          Mid(dtmInstallDate, 7, 2) & "/" & Left(dtmInstallDate, 4) _
          & " " & Mid (dtmInstallDate, 9, 2) & ":" & _
          Mid(dtmInstallDate, 11, 2) & ":" & Mid(dtmInstallDate, _
          13, 2))
      End Function
    ]]>
    </script>
  </job>
</package>

但是运行之后,出来一个提示框:
然后我点确定,没有任何操作。

#5


我的代码不需要修改就可以用的。

#6


这个RemoveFilesByDate.wsf文件双击运行的吗?
我运行过了,但是特定路径下面的文件并不会删除阿。

#7


我双击运行这个文件,弹出一个对话框,上面显示的是这个脚本的版本信息和相关的帮助信息,但是我点击“确定”之后,那个路径下面的文件还是在的,并没有删除?
请问是什么原因?

#8


用2003的forfiles是个选择,你可以把2003的forfiles拷贝过来,然后在脚本里面调用
或者用特种兵的脚本

你提到的三个问题
1、你中文命令的文件有后缀么?奇怪,我这里是没有任何问题的,xp sp2,你什么系统呀?
2、需要同时修改
dir /tc d:\xtmp\tmp\*.*
为dir /a-d /tc d:\xtmp\tmp\*.*
来排除目录
3、与问题2一样,
因为你加了*.*后,会把一个叫.的目录提取出来,就表示上级目录,
会把一个叫..的目录提取出来,表示当前目录,
结果就变成了删除上一级目录和当前目录,所以会出来提示,也就把所有文件删除了

#9


1、我中文命名的文件后缀是.txt的,我是windows2000 advanced server系统
还有一个问题,你的意思是特种兵的脚本需要2003的forfiles?

#10


不是,特种兵的不需要forfiles

晕我找台2000的服务器测试一下再看看

#11


对于第一个问题,我后来仔细的看了一下,原来我那个中文命名的文件,后缀是.txt,因为文件名中带有空格,所以不能删除,我后来尝试了没有空格的汉字命名的文件,确实是可以删除的。
问题是这样出现的,我单击鼠标右键,新建文本文件,默认的文件名是:新建 文本文件.txt,文件名的中间有一个空格,我把这个空格删除之后,就可以了。
但是很奇怪,为什么有空格命名的文件就不可以删除呢?

#12


有空格的当然不行了,
有空格的得用""括起来

#1


呵,有点麻烦哦,建议使用Forfiles.exe这个命令,在2003下可以找到,在2000下一样适用

Forfiles /? 查看帮助

D:>forfiles /?

FORFILES [/P pathname] [/M searchmask] [/S]
         [/C command] [/D [+ | -] {yyyy-MM-dd | dd}]

描述:
    选择一个文件(或一组文件)并在那个文件上
    执行一个命令。这有助于批处理作业。

参数列表:
    /P    pathname      表示开始搜索的路径。默认文件夹是当前工作的
                        目录 (.)。

    /M    searchmask    根据搜索掩码搜索文件。默认搜索掩码是 '*'。

    /S                  指导 forfiles 递归到子目录。像 "DIR /S"。

    /C    command       表示为每个文件执行的命令。命令字符串应该
                        用双引号括起来。

                        默认命令是 "cmd /c echo @file"。下列变量
                        可以用在命令字符串中:
                        @file    - 返回文件名。
                        @fname   - 返回不带扩展名的文件名。
                        @ext     - 只返回文件的扩展。
                        @path    - 返回文件的完整路径。
                        @relpath - 返回文件的相对路径。
                        @isdir   - 如果文件类型是目录,返回 "TRUE";
                                   如果是文件,返回 "FALSE"。
                        @fsize   - 以字节为单位返回文件大小。
                        @fdate   - 返回文件上一次修改的日期。
                        @ftime   - 返回文件上一次修改的时间。

                        要在命令行包括特殊字符,字符请以 0xHH
                        形式使用十六进制代码(例如,0x09 为 tab)。
                        内部 CMD.exe 命令前面应以 "cmd /c" 开始。

    /D    date          选择文件,其上一次修改日期大于或等于 (+),
                        或者小于或等于 (-) 用 "yyyy-MM-dd" 格式指定的日期;
                        或选择文件,其上一次修改日期大于或等于 (+)
                        当前日期加 "dd" 天,或者小于或等于 (-) 当前
                        日期减 "dd" 天。有效的 "dd" 天数可以是
                        0 - 32768 范围内的任何数字。如果没有指定,
                        "+" 被当作默认符号。

    /?                  显示帮助消息。

例如:
    FORFILES /?
    FORFILES
    FORFILES /P C:\WINDOWS /S /M DNS*.*
    FORFILES /S /M *.txt /C "cmd /c type @file | more"
    FORFILES /P C:\ /S /M *.bat
    FORFILES /D -30 /M *.exe
             /C "cmd /c echo @path 0x09 在 30 前就被更改。"
    FORFILES /D 2001-01-01
             /C "cmd /c echo @fname 在 2001年1月1日就是新的。"
    FORFILES /D +2006-11-15 /C "cmd /c echo @fname 今天是新的。"
    FORFILES /M *.exe /D +1
    FORFILES /S /M *.doc /C "cmd /c echo @fsize"
    FORFILES /M *.txt /C "cmd /c if @isdir==FALSE notepad.exe @file"

#2


谢谢,不过我更希望得到的是一个脚本,也就是一个bat文件,呵呵:)
在计划任务中自动运行的,因为现在很多软件的日志很多,我想自动删除。

#3


http://www.secure-code.com/PermaLink,guid,4b1ac99b-236a-492a-8126-6b080d788337.aspx
删除某个目录下预定义天数以前的文件的脚本 


if any question, please send me a PM.

#4


我参照网址提供的,写了一段删除一天以前的文件:
<?xml version="1.0" encoding="gb2312" ?>
<?job error="true" debug="false"?>

<package id="RemoveFilesByDate">

  <job id="Main">
    <runtime>
        <description>
          FileName: RemoveFilesByDate.wsf
          这个脚本删除预定义天数以前的文件.

          Version: 1.0
          Created: icuc88@hotmail.com
          Last Modify: Feb 18th, 2004
          All right reserved.

        </description>
        <named
          name="Driver"
          helpstring="G:"
          type="string"
          required="true"
        />
        <named
          name="Path"
          helpstring="\hqz"
          type="string"
          required="true"
        />
        <named
          name="OlderBy"
          helpstring="1"
          type="string"
          required="false"
        /> 
        <example>
        Example:
          1. 删除3天以前的文件
          RemoveFilesByDate.wsf /Driver:C: /Path:\\test\\

          2. 删除5天以前的文件
          RemoveFilesByDate.wsf /Driver:C: /Path:\\test\\ /OlderBy:5
        </example>
    </runtime>

    <script language="VBScript">
    <![CDATA[
    
      Option Explicit
      On Error Resume Next

      If WScript.Arguments.Count < 2 Then
         WScript.Arguments.ShowUsage
         WScript.Quit
      Else
         ' 从指定的磁盘目录上面查找符合条件的文件
         Dim strComputer
         Dim objWMIService
         Dim colFiles
         Dim objFSO
         strComputer = "." '在本地计算机上执行脚本
         Set objWMIService = GetObject("winmgmts:" _
           & "{impersonationLevel=impersonate}!\\" _
           & strComputer & "\root\cimv2")
         Dim WMISql
         WMISql = "Select * from CIM_DataFile where Path = '" _
           & WScript.Arguments.Named.Item("Path") & "' AND Drive= '" _
           & WScript.Arguments.Named.Item("Driver") & "'" 

         Set colFiles = objWMIService.ExecQuery(WMISql)
         
         ' 删除满足条件的文件
         ' 该脚本指搜索当前路径下面的文件,不搜索子目录
         Set objFSO = CreateObject("Scripting.FileSystemObject")
         
         Dim strWMIDate
         Dim ODate
         Dim OlderBy
         Dim objFile
         For Each objFile in colFiles
           strWMIDate = objFile.CreationDate
           ODate = WMIDateStringToDate(strWMIDate)
           If WScript.Arguments.Named.Item("OlderBy") <> "" Then
             OlderBy = CInt(WScript.Arguments.Named.Item("OlderBy"))
           Else
             OlderBy = 3
           End If
           If (Date - OlderBy) >= ODate Then
             objFSO.DeleteFile(objFile.Name)       
           End If
         Next
      End If

      Function WMIDateStringToDate(dtmInstallDate) '转换WMI格式的日期类型到DateTime类型
        WMIDateStringToDate = CDate(Mid(dtmInstallDate, 5, 2) & "/" & _
          Mid(dtmInstallDate, 7, 2) & "/" & Left(dtmInstallDate, 4) _
          & " " & Mid (dtmInstallDate, 9, 2) & ":" & _
          Mid(dtmInstallDate, 11, 2) & ":" & Mid(dtmInstallDate, _
          13, 2))
      End Function
    ]]>
    </script>
  </job>
</package>

但是运行之后,出来一个提示框:
然后我点确定,没有任何操作。

#5


我的代码不需要修改就可以用的。

#6


这个RemoveFilesByDate.wsf文件双击运行的吗?
我运行过了,但是特定路径下面的文件并不会删除阿。

#7


我双击运行这个文件,弹出一个对话框,上面显示的是这个脚本的版本信息和相关的帮助信息,但是我点击“确定”之后,那个路径下面的文件还是在的,并没有删除?
请问是什么原因?

#8


用2003的forfiles是个选择,你可以把2003的forfiles拷贝过来,然后在脚本里面调用
或者用特种兵的脚本

你提到的三个问题
1、你中文命令的文件有后缀么?奇怪,我这里是没有任何问题的,xp sp2,你什么系统呀?
2、需要同时修改
dir /tc d:\xtmp\tmp\*.*
为dir /a-d /tc d:\xtmp\tmp\*.*
来排除目录
3、与问题2一样,
因为你加了*.*后,会把一个叫.的目录提取出来,就表示上级目录,
会把一个叫..的目录提取出来,表示当前目录,
结果就变成了删除上一级目录和当前目录,所以会出来提示,也就把所有文件删除了

#9


1、我中文命名的文件后缀是.txt的,我是windows2000 advanced server系统
还有一个问题,你的意思是特种兵的脚本需要2003的forfiles?

#10


不是,特种兵的不需要forfiles

晕我找台2000的服务器测试一下再看看

#11


对于第一个问题,我后来仔细的看了一下,原来我那个中文命名的文件,后缀是.txt,因为文件名中带有空格,所以不能删除,我后来尝试了没有空格的汉字命名的文件,确实是可以删除的。
问题是这样出现的,我单击鼠标右键,新建文本文件,默认的文件名是:新建 文本文件.txt,文件名的中间有一个空格,我把这个空格删除之后,就可以了。
但是很奇怪,为什么有空格命名的文件就不可以删除呢?

#12


有空格的当然不行了,
有空格的得用""括起来