Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Скриптовые языки администрирования Windows (http://forum.oszone.net/forumdisplay.php?f=102)
-   -   [решено] Удаление файлов по сети старше 7 дней, оставлять не менее 10 файлов (http://forum.oszone.net/showthread.php?t=223842)

white155 26-12-2011 17:59 1822856

Удаление файлов по сети старше 7 дней, оставлять не менее 10 файлов
 
Задача немного сложнее, нужно удалить все файлы по сети в расшаренной папке,
определённого разрешения, например *.zip в одной папке, старше 7 дней,
при этом оставлять не менее 10 файлов, даже если они старше 7 дней

Iska 28-12-2011 09:50 1823971

white155, Вы уверены насчёт «не старше»? Обычно требуется как раз наоборот — оставлять самые свежие файлы.

white155 30-12-2011 12:10 1825508

исправил

Iska 30-12-2011 21:18 1825820

white155, ясно.

Попробую и Вас приобщить к библиотеке Log Parser (Download: Log Parser 2.2 - Microsoft Download Center - Download Details).

Примерный код:
читать дальше »
Код:

Option Explicit

Dim strMask

Dim objLogQuery
Dim objFileSystemInputFormat
Dim strQuery

Dim objDictionary
Dim objFSO


strMask = "E:\Песочница\0102\*.zip"

Set objLogQuery              = WScript.CreateObject("MSUtil.LogQuery")
Set objFileSystemInputFormat = WScript.CreateObject("MSUtil.LogQuery.FileSystemInputFormat")

Set objDictionary            = WScript.CreateObject("Scripting.Dictionary")
Set objFSO                  = WScript.CreateObject("Scripting.FileSystemObject")

With objFileSystemInputFormat
        .preserveLastAccTime = True
        .recurse            = False
        .useLocalTime        = True
End With

strQuery = _
        "SELECT TOP 10 LastWriteTime, Path " & _
        "FROM '" & strMask & "' " & _
        "WHERE Attributes NOT LIKE 'D________' " & _
        "ORDER BY LastWriteTime DESC"

With objLogQuery.Execute(strQuery, objFileSystemInputFormat)
        Do Until .atEnd()
                With .getRecord()
                        objDictionary.Add .toNativeString(1), .toNativeString(1)
                End With
               
                .moveNext
        Loop
       
        .close
End With

strQuery = _
        "SELECT Path " & _
        "FROM '" & strMask & "' " & _
        "WHERE Attributes NOT LIKE 'D________' " & _
        "ORDER BY Path ASC"

With objLogQuery.Execute(strQuery, objFileSystemInputFormat)
        Do Until .atEnd()
                With .getRecord()
                        If Not objDictionary.Exists(.toNativeString(0)) Then
                                WScript.Echo .toNativeString(0)
                               
                                'objFSO.DeleteFile .toNativeString(0), True
                        End If
                End With
               
                .moveNext
        Loop
       
        .close
End With

objDictionary.RemoveAll

Set objFSO                  = Nothing
Set objDictionary            = Nothing

Set objFileSystemInputFormat = Nothing
Set objLogQuery              = Nothing

WScript.Quit 0

Здесь:
Код:

strMask = "E:\Песочница\0102\*.zip"
— путь и маска к сетевому ресурсу;
Код:

With objFileSystemInputFormat
        …
        .recurse            = False

— не обрабатывать вложенные папки.

По самому алгоритму:
Код:

strQuery = _
        "SELECT TOP 10 LastWriteTime, Path " & _
        "FROM '" & strMask & "' " & _
        "WHERE Attributes NOT LIKE 'D________' " & _
        "ORDER BY LastWriteTime DESC"

— выбрать поля: дату последней записи и путь (SELECT TOP 10 LastWriteTime, Path) к файлам (Attributes NOT LIKE 'D________') по указанной маске «E:\Песочница\0102\*.zip» (FROM '" & strMask & "'), отсортированным по дате последней записи в обратном порядке (ORDER BY LastWriteTime DESC). Из полученного списка отобрать только первые десять записей (TOP 10). Таким образом, мы получаем пути к файлам, которые нужно будет сохранить (не удалять).

Затем мы перебираем полученный список и заполняем им словарь «objDictionary».

Второй запрос:
Код:

strQuery = _
        "SELECT Path " & _
        "FROM '" & strMask & "' " & _
        "WHERE Attributes NOT LIKE 'D________' " & _
        "ORDER BY Path ASC"

— тут просто отбираем пути всех подходящих под заданную маску файлов. Полученный список путей файлов мы перебираем и удаляем все, которые не попали в первый запрос и не содержатся в словаре (If Not objDictionary.Exists(.toNativeString(0)) … objFSO.DeleteFile .toNativeString(0), True).

Вот, собственно, и весь алгоритм.

P.S. Для удаления файлов уберите комментарий при:
Код:

                                'objFSO.DeleteFile .toNativeString(0), True
P.P.S. Можно, конечно, не делать два запроса, а убрать «TOP 10» первом запросе и просто пропустить при переборе первые десять файлов, а все оставшиеся файлы полученного набора — удалять.


Если у Вас есть возможность использовать PowerShell — можно попробовать и так:
читать дальше »
Код:

Get-ChildItem -Path "E:\Песочница\0102\*.zip" | `
    Sort-Object -Property LastWriteTime -Descending | `
        Select-Object -Skip 10 | `
            Remove-Item -WhatIf -Force

Не правда ли, выглядит проще?!

P.S. Для реального удаления уберите параметр «-WhatIf» у команды «Remove-Item».

introvert 31-12-2011 10:53 1826039

Iska, вопрос, вроде бы, несколько по другому сформулирован

оставить все файлы не старше 7дней и если их меньше 10, добавить из тех что старше 7 дней

Iska 31-12-2011 16:01 1826150

introvert, осознал свою ошибку: свежих файлов может оказаться куда больше десяти. Подумаем, как и это учесть. Жаль, красоты в коде тут уже не будет :(.

megaloman 04-01-2012 00:42 1827886

Код:

' Скрипт оставляет в указанной папке не менее указанного числа свежих файлов с указанным расширением (если они есть)
' Если среди оставшихся файлов имеются старше указанного кол-ва дней, они удаляются

fPath = "E:\DelShare"  ' Полное имя рабочего каталога (без слэжа \ на конце)
fExt = "bat"            ' Расширение файлов
nMin = 10              ' Минимальное число оставляемых файлов
nOld = 7                ' Старше кол-ва дней файлы удаляем

OldDate = DateAdd("d", -nOld, Date)
'  MsgBox CStr(OldDate)

Set FSO = CreateObject("Scripting.FileSystemObject")
Set Folds = FSO.GetFolder(fPath)
Set Files = Folds.Files

N = Files.Count - 1
'  MsgBox CStr(N)

If N < 0 Then
    MsgBox "В папке" + vbCrLf + fPath + vbCrLf + "файлы не найдены"
Else
    ReDim nFiles(N), dFiles(N)
    NN = -1
    For Each jf In Files
        nFiles(NN + 1) = jf.Name
        If LCase(FSO.GetExtensionName(fPath + "\" + nFiles(NN + 1))) = LCase(fExt) Then
            NN = NN + 1
            dFiles(NN) = jf.DateLastModified
        End If
    Next
    If NN < 0 Then
        MsgBox "В папке" + vbCrLf + fPath + vbCrLf + "файлы c расширением " + fExt + vbCrLf + " не найдены"
    Else
        For i = 0 To NN
            For j = i To NN
                If dFiles(i) < dFiles(j) Then
                    df = dFiles(i)
                    dFiles(i) = dFiles(j)
                    dFiles(j) = df
                    nf = nFiles(i)
                    nFiles(i) = nFiles(j)
                    nFiles(j) = nf
                End If
            Next
            '  MsgBox CStr(dFiles(i)) + " " + nFiles(i)
        Next
        If NN > nMin - 1 Then
            For i = nMin To NN
                '  MsgBox CStr(dFiles(i)) + " " + nFiles(i)
                If dFiles(i) < OldDate Then Call FSO.DeleteFile(fPath + "\" + nFiles(i), True)
            Next
        End If
    End If
   
End If

Длинновато.
1. Записываю имена и даты изменения файлов в массивы
2. Сортирую по датам по убыванию
3. Просматриваю в массиве с датами файлов элементы более минимального количества
Старые файлы удаляю


Время: 01:33.

Время: 01:33.
© OSzone.net 2001-