zoukankan      html  css  js  c++  java
  • 用批处理文件删除n天前的文件

    原文:http://blog.csdn.net/leehq/archive/2007/08/03/1723743.aspx

    公司服务器用来备份数据的硬盘过段时间就会被备份文件占满,弄得我老是要登录到服务器去手工删除那些老的文件,有时忘记了就会导致硬盘空间不足而无法备份。
    因为只要保留最近几天的备份,如果可以做一个批处理让系统自动删除老备份文件就好了,但是Windows的命令行和Linux的Shell比起来功能差了很多,到底行不行我自己也不清楚。
    于是上网查了一下各位大虾发的帖子,再经过自己的摸索和尝试,发现只要花点功夫还是能实现这个功能的。
    下面来看看我的实现方法。

    如果操作系统是 Windows Server 2003 那就好办了,因为它有一个forfiles命令能够查找满足指定条件的文件,下面是这个命令的用法。
    forfiles /p <目标目录名> /d <天数> /c <执行的命令>
    看看列出的三个参数都有什么用处:
    /p 指定了要在哪个目录里查找文件,默认是当前工作目录,注意不能在目录名后面加斜杠。
    /d 指定一个日期或天数,用于比较文件的最后修改日期是否符合条件。
    /c 对每个找到的文件执行的命令。

    例1.要把在C盘根目录下最后修改日期大于或等于2007年7月1日的文件复制到D盘根目录下:
    forfiles /p "c:" /d "2007-7-1" /c "cmd /c copy @path d:"
    例2.删除在C盘backup目录下最后修改日期在10天前的文件:
    forfiles /p "c:ackup" /d -10 /c "cmd /c echo deleting @file ... && del /f @path"

    看了上面的例子,觉得在 Windows Server 2003 下面要删除老文件很简单吧。
    但如果操作系统是 Windows 2000/XP 就比较麻烦,因为它们没有forfiles命令,只能靠自己写批处理来实现了。
    下面是我写的批处理文件内容:

    @echo off

    rem ******************************
    rem * 按时间删除文件目录的批处理 *
    rem ******************************

    rem 设置临时目录的路径
    set tempDir=%tmp% emove_%date:~0,10%
    if not exist %tempDir% md %tempDir%
    rem 设置处理日期的脚本文件的路径
    set scriptFile=%tempDir%get_date.vbs

    rem 获得要保留的天数
    set days=%~1
    if "%days%" == "" goto printUsage
    rem 获得目标目录的路径
    set dirPath=%~2
    if "%dirPath%" == "" set dirPath=.
    rem 获得要操作的文件形式
    set fileSpec=%~3
    if "%fileSpec%" == "" set fileSpec=*.*

    rem 生成计算日期的脚本文件并获得删除的截止日期
    echo d=date()-%1 > %scriptFile%
    echo s=right("0000" ^& year(d),4) ^& "-" ^& right("00" ^& month(d),2) ^& "-" ^& right("00" ^& day(d),2) >> %scriptFile%
    echo wscript.echo s >> %scriptFile%
    for /f %%i in ('cscript /nologo %scriptFile%') do set lastDate=%%i

    rem 处理目标目录里的每个对象
    for /f "tokens=1,2,3* delims=<> " %%i in ('dir "%dirPath%\%fileSpec%" /a /-c /tc') do call :proc "%%i" "%%j" "%%k" "%%l"
    goto :done

    rem 处理目标目录里对象的过程
    :proc
    rem 获得对象的创建日期并判断是否为有效格式
    set fileDate=%~1
    echo %fileDate% | findstr "[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]" > nul
    if errorlevel 1 goto end
    rem 获得对象的类型
    set fileType=%~3
    if "%fileType%" == "" goto end
    rem 获得对象的名称
    set fileName=%~4
    if "%fileName%" == "" goto end
    if "%fileName%" == "." goto end
    if "%fileName%" == ".." goto end
    if "%fileName%" == "字节" goto end
    if "%fileName%" == "可用字节" goto end
    rem 判断对象日期是否小于或等于删除的截止日期
    if "%fileDate:~0,10%" leq "%lastDate%" (
     echo deleting "%fileName%" ...
     if "%fileType%" == "DIR" ( rd /s /q "%dirPath%\%fileName%" ) else ( del /q /f "%dirPath%\%fileName%" )
    )
    goto end

    :error
    echo An error occurred during backuping.

    :done
    rd /s /q %tempDir%
    goto end

    :printUsage
    echo Usage: %0 ^<Days^> [Work directory] [Target file specification (can include wildcards)]
    goto end

    :end

    这个批处理的语句很多,我表达能力有限,懒得一一解释了。
    主要是利用Windows的脚本功能来计算要删除文件的截止日期,然后for加dir命令来提取文件的日期进行判断。

    关于forfiles和for的详细信息,可以在Windows的帮助与支持中找到。 

    附:

    forfiles指令介紹

    在 WINDOWS 下, 若是要將某些檔案做什麼處理的方式, 我通常使用 VBS 的 SCRIPT 來操作, 不過其實還有更方便簡捷的方法, 看到這篇文章 windows server下的檔案處理程式Forfiles , 原來其實在 windows 下還有個這麼方便的檔案列舉工具.

    一般最常用的是刪除 log 檔案, 指定目錄, 並指令時間 (例如保留一週, 一週前的刪除), 就可以利用這個指令進行刪除:

    forfiles /p c: emp /s /m *.log /d -7 /c "cmd /c del @FILE"

    或是列舉出指定目錄下的檔案(非目錄)的名稱列出:

    forfiles /p c: /c "cmd /c if @isdir==FALSE echo @FILE"

    請注意上面的 "FALSE" 要大寫!

    再來看看微軟的官方說明: Forfiles

    以下列出該指令的參數說明: (利用 forfiles /? 取得)

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

    描述:
        選取一個檔案 (或一組檔案),並在檔案上
        執行命令。這對批次工作很有幫助。

    參數清單:
        /P    pathname      表示要開始搜尋的路徑。
                            預設資料夾是目前的
                            目錄 (.)。

        /M    searchmask    根據 searchmask 搜尋檔案。
                            預設的 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 was changed 30 days ago"
        FORFILES /D 2001/01/01
                 /C "cmd /c echo @fname is new since Jan 1st 2001"
        FORFILES /D +2008/7/13 /C "cmd /c echo @fname is new today"
        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"

  • 相关阅读:
    LeetCode 88. Merge Sorted Array
    LeetCode 75. Sort Colors
    LeetCode 581. Shortest Unsorted Continuous Subarray
    LeetCode 20. Valid Parentheses
    LeetCode 53. Maximum Subarray
    LeetCode 461. Hamming Distance
    LeetCode 448. Find All Numbers Disappeared in an Array
    LeetCode 976. Largest Perimeter Triangle
    LeetCode 1295. Find Numbers with Even Number of Digits
    如何自学并且系统学习计算机网络?(知乎问答)
  • 原文地址:https://www.cnblogs.com/xunbu7/p/3509623.html
Copyright © 2011-2022 走看看