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

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

Sony777 20-12-2011 20:04 1818963

Удаление файлов по дате больших размеров.
 
Помогите разобраться пожалуйста. Я нашел скрипт, который хорошо выполняет свою функцию, удаляя устаревшие папки, но оставляя всегда нужное фиксированное количество резерва. Вот он:

@echo off
SetLocal EnableExtensions

set BackUp=MyDisk:\MyBackUp
set Num=10

pushd %BackUp%
for /f "tokens=* delims=" %%D in ('dir /ad /b /o-d') do call :Proceed "%%D"
popd
exit

:Proceed
if not %Num%==0 set /a Num-=1&exit /b
echo %date% %time%: Erase %1>>%~dpn0.log
rd /s /q %1 2>nul >nul
exit /b

Но есть 2 нюанса и соответственно в них и нужна помощь.
1. Этот скрипт не справляется вообще никак при работе с файлами очень больших размеров. А нужно удалять файлы объемом от 100ГБ+.
2. Когда очень много директорий, то приходиться прописывать условие и цикл для каждой директории, что конечно не есть хорошо. И кода много и батник при исполнении получается огромным.
Помогите разобраться плиз. За ранее спасибо.

Sony777 21-12-2011 17:08 1819533

Цитата:

Цитата megaloman
А почему бы не воспользоваться vbs или js ? »

Я не против, знать бы как)

megaloman 21-12-2011 17:26 1819542

1. Этот скрипт не справляется вообще никак при работе с файлами очень больших размеров - А почему бы не воспользоваться vbs или js ?

2. Как понять: Когда очень много директорий, то приходиться прописывать условие и цикл для каждой директории, Речь идёт о директориях, находящихся в папке, описываемой в set BackUp=MyDisk:\MyBackUp, судя по организации цикла 'dir /ad /b /o-d вложенные директории не анализируются? Почему бы не написать нечто подобное:
Код:

@Echo Off

Do Call :SubRoutine "C:\Program Files"
Do Call :SubRoutine "C:\Windows"

GoTo :Eof

:SubRoutine
Set Num=10
Pushd %1

Echo --------------------------------------------------->>%~dpn0.log
Echo %1>>%~dpn0.log
Echo --------------------------------------------------->>%~dpn0.log

For /F "usebackq delims=" %%d in (`Dir /b /A:D /O:-D`) Do Call :Proceed "%%d"
Popd
GoTo :Eof

:Proceed
Set /A Num-=1
If %Num% GEQ 0 GoTo :Eof

Echo %Date%  %Time%: Erase %1>>%~dpn0.log
rem                    rd /s /q %1 2>nul >nul

либо
Код:

@Echo Off

For %%i In ("C:\Program Files" "C:\Windows") Do Call :SubRoutine %%i
GoTo :Eof

Далее подпрограммы взять из предыдущего кода

По понятным причинам (я указал директории "C:\Program Files" "C:\Windows" чтобы посмотреть выборку) удаление я заремил - подправьте в Вашем реальном случае

3. Как понять: но оставляя всегда нужное фиксированное количество резерва - в чем резерв измеряется? Похоже, вы удаляете 10 старых директорий и иначе их никак не анализируете.

Sony777 21-12-2011 19:35 1819634

Цитата:

Цитата megaloman
Как понять: Когда очень много директорий, то приходиться прописывать условие и цикл для каждой директории, Речь идёт о директориях, находящихся в папке, описываемой в set BackUp=MyDisk:\MyBackUp, судя по организации цикла 'dir /ad /b /o-d вложенные директории не анализируются? Почему бы не написать нечто подобное: »

Скрипт был написан для одной директории. Но в моем случае их Н-ое количество. Поэтому я описывал каждую директорию отдельно и для каждой директории условие и цикл...
Цитата:

Цитата Sony777
Как понять: но оставляя всегда нужное фиксированное количество резерва - в чем резерв измеряется? Похоже, вы удаляете 10 старых директорий и иначе их никак не анализируете. »

По поводу резерва, там по идее удаляется старое и остаются последние 10.

megaloman 21-12-2011 20:46 1819700

Я исправил свой ответ в соответствии с Вашими разъяснениями.
В батниках можно описать множество директорий то ли в цикле, то ли вызывая подпрограмму с именем конкретной директории в каждой строке.
Вот vbs-скрипт, по действию аналогичный батнику
Код:

NMax = 10
MyDirs = Array("E:\Dir1", _
            "E:\Dir2", _
            "E:\Dir3")

LogFile = WScript.ScriptFullName + ".Log"

NN = UBound(MyDirs)

Set FSO = CreateObject("Scripting.fileSystemObject")
Set FLog = FSO.OpenTextFile(LogFile, 8, True)

FLog.WriteLine "=========================="
FLog.WriteLine CStr(Date) + "  " + CStr(Time)
FLog.WriteLine "=========================="

For i = 0 To NN
    FLog.WriteLine vbCrLf + MyDirs(i)
   
    Set F = FSO.GetFolder(MyDirs(i))
    Set SubF = F.SubFolders
   
    NDir = SubF.Count - 1
    ReDim dSub(NDir), nSub(NDir)
   
    j = 0
    For Each Folder In SubF
        nSub(j) = MyDirs(i) + "\" + Folder.Name
        dSub(j) = Folder.DateLastModified
        j = j + 1
    Next
   
    For j = 0 To NDir
'        If j > NMax - 1 Then Exit For
        For k = j To NDir
            If dSub(j) < dSub(k) Then
                dd = dSub(j)
                dSub(j) = dSub(k)
                dSub(k) = dd
                nd = nSub(j)
                nSub(j) = nSub(k)
                nSub(k) = nd
            End If
        Next
    Next
   
    M = MyDirs(i)
    If NDir >= NMax Then
            For j = NMax To NDir
                M = M + vbCrLf + CStr(dSub(j)) + "  " + nSub(j)
                FLog.WriteLine CStr(dSub(j)) + "  " + nSub(j)
'                FSO.DeleteFolder nSub(j), True
            Next
    End If

'    MsgBox M

Next
FLog.WriteLine vbCrLf
FLog.Close

Скрипт ничего не удаляет, так как строка с удалением закомментирована
' FSO.DeleteFolder nSub(j), True
Для реальной работы удалите в этой строке '

Sony777 22-12-2011 12:52 1820056

megaloman, благодарочка! Сейчас тестирую.

Sony777 23-12-2011 16:59 1820928

В общем у себя на машине локально протестировав, можно сказать что скрипт работает. Но на сервере в шедуллере он запускается, висит в раннинг, но ничего не происходит. :\

Sony777 25-12-2011 12:13 1821896

Цитата:

Цитата megaloman
1. На сервере не в шедуллере скрипт работает?
2. От чьего имени в шедуллере запускается скрипт? Хватает ли прав на удаление? Я не предусмотрел в скрипте обработку ошибочной ситуации, если прав на удаление не хватает - скрипт должен выскочить на ошибку. И, если скрипт запущен не от имени пользователя, с которым вы вошли в систему, никаких сообщений на рабочий стол Вы не получите. В принципе, обработку несложно сделать, но хотелось бы разобраться в ситуации. Кстати, а не в том ли причина, что батник не удаляет Ваши папки? Я не встречал упоминаний об ограничении размеров удаляемых командой del или RD файлов - был бы благодарен всем, кто мне на это доказательно укажет - для меня 100Гб слишком большой объём, чтобы его смоделировать. »

1.Да, скрипт работает в шедуллере.
2.Загвоздка была таки в учетках))) Сейчас поковырявшись стало все ок.
Скрипт работает и удаляет быстро. Все пока хорошо. Спасибо вам большое)

sv_ua 25-05-2012 22:25 1922713

Прошу помочь с такой задачей: на N дисках в директориях вида _Dir_ (одинаковых на всех N дисках) есть архив состоящий из папок с названиями типа YYMMDD (год месяц день, например 120525). Стоит задача хранить архивы не менее 300 дней. Проблема состоит в том, что программа, создающая эти папки может создать папки с одинаковыми названиями одновременно на разных дисках. Естественно, удалять желательно все папки данного дня, т.е. считать x папок на x дисках как одну, если у них одинаковое имя.
Можно ли научить вышеприведенный скрипт выполнять такую задачу?


Кстати, если в данном скрипте в строке:

dSub(j) = Folder.DateLastModified

заменить на

dSub(j) = Folder.Name

то скрипт замечательно удаляет именно самые старые папки.

Буде очень признателен за помощь.

Iska 26-05-2012 23:28 1923147

Цитата:

Цитата sv_ua
…программа, создающая эти папки может создать папки с одинаковыми названиями одновременно на разных дисках. »

Это как?

Евгений_Темный@fb 29-05-2012 14:57 1924500

Код:

disk = Array ("C:", "D:")                        ' перечисление дисков в скобках
search_dir = "_RecordVideo_"                ' директория поиска
limit = 20                ' предельное кол-во свободного места на жестком диске в Гб
k = 30                        ' кол-во дней

Set fso = CreateObject ("Scripting.FileSystemObject")
logfile = Left(WScript.ScriptName, Len(WScript.ScriptName) - 4)
Set logfile = fso.OpenTextFile(logfile & ".log", 8, True)
For i = 0 To UBound(disk)
        fs = fso.GetDrive(disk(i)).FreeSpace / (1024 * 1024 * 1024)
        If fs < limit Then
                Set fold = fso.GetFolder(disk(i) & "\" & search_dir)
                For Each subfold In fold.SubFolders
                        data_cr = subfold.DateCreated
                        data_fold = Right(subfold.Name, 2) & "." & Mid(subfold.Name, 3, 2) & "." & Left(subfold.Name, 2)
                        d1 = DateDiff("d", data_cr, Date())
                        d2 = DateDiff("d", data_fold, Date())
                        If d1 > k Or d2 > k Then
                                logfile.WriteLine Now() & " Директория " & subfold.Path & " удалена"
                                subfold.Delete
                        End If
                Next
        End If
Next


sv_ua 03-06-2012 16:23 1927273

Огомное спасибо Евгений_Темный@fb, скрипт кажется работает, буду тестировать на рабочей системе!


Время: 14:31.

Время: 14:31.
© OSzone.net 2001-