Удаление файлов по дате больших размеров.
Помогите разобраться пожалуйста. Я нашел скрипт, который хорошо выполняет свою функцию, удаляя устаревшие папки, но оставляя всегда нужное фиксированное количество резерва. Вот он:
@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. Когда очень много директорий, то приходиться прописывать условие и цикл для каждой директории, что конечно не есть хорошо. И кода много и батник при исполнении получается огромным.
Помогите разобраться плиз. За ранее спасибо.
|
Цитата:
Цитата megaloman
А почему бы не воспользоваться vbs или js ? »
|
Я не против, знать бы как)
|
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 старых директорий и иначе их никак не анализируете.
|
Цитата:
Цитата megaloman
Как понять: Когда очень много директорий, то приходиться прописывать условие и цикл для каждой директории, Речь идёт о директориях, находящихся в папке, описываемой в set BackUp=MyDisk:\MyBackUp, судя по организации цикла 'dir /ad /b /o-d вложенные директории не анализируются? Почему бы не написать нечто подобное: »
|
Скрипт был написан для одной директории. Но в моем случае их Н-ое количество. Поэтому я описывал каждую директорию отдельно и для каждой директории условие и цикл...
Цитата:
Цитата Sony777
Как понять: но оставляя всегда нужное фиксированное количество резерва - в чем резерв измеряется? Похоже, вы удаляете 10 старых директорий и иначе их никак не анализируете. »
|
По поводу резерва, там по идее удаляется старое и остаются последние 10.
|
Я исправил свой ответ в соответствии с Вашими разъяснениями.
В батниках можно описать множество директорий то ли в цикле, то ли вызывая подпрограмму с именем конкретной директории в каждой строке.
Вот 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
Для реальной работы удалите в этой строке '
|
megaloman, благодарочка! Сейчас тестирую.
|
В общем у себя на машине локально протестировав, можно сказать что скрипт работает. Но на сервере в шедуллере он запускается, висит в раннинг, но ничего не происходит. :\
|
Цитата:
Цитата megaloman
1. На сервере не в шедуллере скрипт работает?
2. От чьего имени в шедуллере запускается скрипт? Хватает ли прав на удаление? Я не предусмотрел в скрипте обработку ошибочной ситуации, если прав на удаление не хватает - скрипт должен выскочить на ошибку. И, если скрипт запущен не от имени пользователя, с которым вы вошли в систему, никаких сообщений на рабочий стол Вы не получите. В принципе, обработку несложно сделать, но хотелось бы разобраться в ситуации. Кстати, а не в том ли причина, что батник не удаляет Ваши папки? Я не встречал упоминаний об ограничении размеров удаляемых командой del или RD файлов - был бы благодарен всем, кто мне на это доказательно укажет - для меня 100Гб слишком большой объём, чтобы его смоделировать. »
|
1.Да, скрипт работает в шедуллере.
2.Загвоздка была таки в учетках))) Сейчас поковырявшись стало все ок.
Скрипт работает и удаляет быстро. Все пока хорошо. Спасибо вам большое)
|
Прошу помочь с такой задачей: на N дисках в директориях вида _Dir_ (одинаковых на всех N дисках) есть архив состоящий из папок с названиями типа YYMMDD (год месяц день, например 120525). Стоит задача хранить архивы не менее 300 дней. Проблема состоит в том, что программа, создающая эти папки может создать папки с одинаковыми названиями одновременно на разных дисках. Естественно, удалять желательно все папки данного дня, т.е. считать x папок на x дисках как одну, если у них одинаковое имя.
Можно ли научить вышеприведенный скрипт выполнять такую задачу?
Кстати, если в данном скрипте в строке:
dSub(j) = Folder.DateLastModified
заменить на
dSub(j) = Folder.Name
то скрипт замечательно удаляет именно самые старые папки.
Буде очень признателен за помощь.
|
Цитата:
Цитата 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
|
Огомное спасибо Евгений_Темный@fb, скрипт кажется работает, буду тестировать на рабочей системе!
|
Время: 14:31.
© OSzone.net 2001-