2009-11-23 46 views
0

在一个文件夹内(如c:\ test)我想删除最旧的文件,如果文件数超过21个。如何让我的批处理脚本可以删除旧文件?

这是我想出的问题是它一次删除最旧的文件,第二次运行它什么也不做,并删除最老的第三,继续这样。也不关心文件数量是否低于21,即使更低也会删除。

下面是代码:

SET BACKUPDIR=C:\test 
SET countfiles=dir BACKUPDIR /b | find /v /c "::" 

if countfiles GTR 21 (
FOR /F %%i IN ('DIR /B /O-D %BACKUPDIR%') DO SET OLDEST=%%i 
DEL %BACKUPDIR%\%OLDEST% 
) 
+2

我会尝试你这个调试自己,但怎么样我只是告诉你我会怎么做。首先,坚持一些回声陈述。在前两个'SET'语句之后添加一行'echo countfiles =%countfiles%'和'echo BACKUPDIR =%BACKUPDIR%'。然后在'IF'语句中添加一行,如'echo countfiles> 21>。简单的调试技术可能会让您自己发现故障。 – 2009-11-23 00:18:39

+0

@PP:我thik这将是一个很好的答案或至少一个很好的指针:) – 2009-11-23 00:23:50

回答

1

这里是在VBScript中的另类,,遍历该目录只有一次。

Set objFS=CreateObject("Scripting.FileSystemObject") 
Set objArgs = WScript.Arguments 
strFolder = objArgs(0) 
strScriptName = WScript.ScriptFullName 'get script name 
Set objFolder = objFS.GetFolder(strFolder) 
Set dict = CreateObject("Scripting.Dictionary") 
current = Now 
temp=0 
count=0 'count files 
For Each strFile In objFolder.Files 
    If strFile.Path <> strScriptName Then 'do if not script name 
     count=count+1 
     dict.Add strFile.Path, strFile.DateLastModified 
     'if there are more than 21 files 
     If count >= 21 Then 
     flag=1 
     End If 
    End If 
Next 

filedate = dict.Items 
filename = dict.keys 
If flag = 1 Then 
    For i = 0 To dict.Count -1 'iterate dictionary 
     diffdate = DateDiff("d",filedate(i),now) 
     If num_days_diff >= temp Then 
     oldestfile = filename(i) 
     oldestdate = filedate(i) 
     temp = num_days_diff 
     End If    
    Next 
End If 
Set dict=Nothing 
WScript.Echo "Oldest file: " & oldestfile, oldestdate 
objFS.DeleteFile(oldestfile) 

另存为deletefile.vbs和命令行

c:\test> cscript /nologo deletefile.vbs c:\path\somewhere 
+0

非常感谢输入,但是我在此看到一个问题,除非将它放到“C:\ test”,否则它不起作用。如果我在“C:\ test”下运行它,它会自行删除:)我对vbscripting非常陌生,它怎么能从远程目录运行它(即从“C:\”执行它。干杯 – Hellnar 2009-11-23 08:58:01

+1

你可以使用参数我已编辑过包含参数你是什么意思删除“本身?” – ghostdog74 2009-11-23 09:37:21

+0

它只在将它放到文件目录时才起作用,并且由于脚本本身就是一个文件,它正在删除脚本文件:) – Hellnar 2009-11-23 14:05:11

4

有许多与此问题。

  1. 环境变量与文本字符串:

    SET countfiles=dir BACKUPDIR /b | find /v /c "::" 
    

    在这里,我们试图在一个名为“BACKUPDIR”目录中列出的文件,而不是使用环境变量。它应该是

    SET countfiles=dir %BACKUPDIR% /b | find /v /c "::" 
    
  2. 你获得的文件数量的尝试:

    SET countfiles=dir %BACKUPDIR% /b | find /v /c "::" 
    

    不可能工作。这只是将字符串'dir BACKUPDIR /b | find /v /c "::" '分配给环境变量countfiles。它不会运行任何东西 - cmd应该如何知道这是一个要执行的命令?

    你想要的是以下几点:

    for /f %%x in ('dir %BACKUPDIR% /b ^| find /v /c "::"') do set countfiles=%%x 
    

    这将countfiles环境变量的内容设置为上述命令的输出。您可以通过help for找到更多相关信息。

  3. 您的比较:

    if countfiles GTR 21 
    

    这个比较"countfiles"和字符串"21"。并且由于countfiles21之后得到排序,所以此情况将始终为真。

    你想使用环境变量%countfiles%这里:

    if %countfiles% GTR 21 
    
  4. 你试试“正常”,“块”中的变量扩展:

    ​​

    由于cmd在解析时立即展开环境变量一个命令会导致问题。请注意,上面的块作为cmd的单个命令。完整的程序块在运行前会被解析,并且所有的变量在运行时都会被替换掉,所以这不是正确的方法来处理那些可能会改变这个块的变量

    这里的解决方案是延迟扩展。您可以包括您的批处理开始下面一行:

    ​​

    而是采用可变像%OLDEST%您使用!OLDEST!和。 !也扩展了变量,但是在执行之前直接执行,而不是在解析时执行。所以,你的代码段会成为:

    if %countfiles% GTR 21 (
        FOR /F %%i IN ('DIR /B /O-D %BACKUPDIR%') DO SET OLDEST=%%i 
        DEL %BACKUPDIR%\!OLDEST! 
    ) 
    
  5. 万一你期待与空格的文件名时,for /f循环中的最后一块没有达到预期效果。你可以修改它是这样的:

    for /f "delims=" %%i in ... 
    

    这确保了线不破的空间(你会得到公正的第一个标记,到第一个空格的文件的名称,而不是完整的文件。名字

所以,总结,你的程序可能看起来像下面这样:

SET BACKUPDIR=C:\test 
for /f %%x in ('dir %BACKUPDIR% /b ^| find /v /c "::"') do set countfiles=%%x 

if %countfiles% GTR 21 (
    FOR /F "delims=" %%i IN ('DIR /B /O-D %BACKUPDIR%') DO SET OLDEST=%%i 
    DEL %BACKUPDIR%\!OLDEST! 
) 

,并应大致工作,我没有测试过它(床话费)每一个方面,但我。确信它有效比以前更好,我希望你能理解上面的修正和为什么它们是必要的。

顺便说一句:find /v /c "::"是一个漂亮的小动作。不知道那一个或想到它。

以防万一:如果您确实想继续删除最旧的文件,直到您的文件数降至21以下,那么该单一的if将不会削减它。您需要设置一个循环,要么继续迭代并重新计算每次迭代,要么计算需要删除的文件数量。尽管如此,我将把它作为一个练习。 (提示:循环可以有标签和条件goto S或使用for /l完成后者需要更多的延迟扩展,虽然,所以要小心。)

+0

非常感谢输入Johannes,特别是向我展示我的错误,因为我更倾向于使用Linux(所以bash脚本),这是一个有趣的经验。同时你建议的代码不起作用。以下是可能解释所有内容的屏幕截图:):http://img692.imageshack.us/img692/2199/deletex.jpg 致以问候 – Hellnar 2009-11-23 09:08:57

+1

呃,我非常抱歉,我错过了那一个。你应该在''''''''''dir'命令中加入'BACKUPDIR'命令:'dir%BACKUPDIR%/ b'来起诉环境变量,而不是尝试找到一个名为“BACKUPDIR”的目录。 – Joey 2009-11-23 10:03:39

+1

好的,编辑了更改。希望我没有忘记一个实例。 – Joey 2009-11-23 10:05:35

相关问题