PDA

Показать полную графическую версию : Удаление файлов старше Д дней, Н недель, М месяцев


etherlord
16-03-2016, 19:39
Здравствуйте, стала задача удалять файлы из папок с бекапами, по заданным критериям:
оставлять 1 файл в день старше Д дней
оставлять 1 файл в неделю старше Н недель
и 1 файл\мес старше М Месяцев.

пока только работаю над логикой и вот что получается:

Param(
[Parameter(Mandatory=$true)][string]$path,
[Parameter(Mandatory=$false)][int]$days,
[Parameter(Mandatory=$false)][int]$weeks,
[Parameter(Mandatory=$false)][int]$month,
)

$date = Get-date
$day = days

do {
gci $path |
Where-Object { ($_.LastWriteTime -lt (get-date).AddDays(-$day)) -and
($_.LastWriteTime -gt (get-date).AddDays(-$day+1)) -and
!$_.PSIsContainer
} | Select -Skip 1 | Remove-Item -Force -WhatIf
$day++
until ($day -gt ($weeks*7))

$currentWeek=$weeks
do {
gci $path |
Where-Object { ($_.LastWriteTime -lt (get-date).AddDays(-($currentWeek*7))) -and
($_.LastWriteTime -gt (get-date).AddDays(-(($currentWeek+1)*7))) -and
!$_.PSIsContainer
} | Select -Skip 1 | Remove-Item -Force -WhatIf
$currentWeek++
until ((get-date).AddDays(-($currentWeek*7)) -lt (get-date).AddMonths(-($month)))

$currentMonth=$month
do {
gci $path |
Where-Object { ($_.LastWriteTime -lt (get-date).AddMonths(-$currentMonth)) -and
($_.LastWriteTime -gt (get-date).AddMonths(-($currentMonth+1))) -and
!$_.PSIsContainer
} | Select -Skip 1 | Remove-Item -Force -WhatIf
$currentMonth++
until ($currentMonth -gt 12)

Собственно вопрос насколько корректо я это написал, и как остановить скрипт, пока он не ушел в 1980 или еще глубже.
Так же меня беспокоит что будет море запросов, если например на сервере хранится миллион файлов, то этот скипт создат прямо таки IOPs шторм.

greg zakharov
17-03-2016, 10:02
Дык понятное дело: обращение по нескольку раз к одной и той же папке с пропуском полученных данных всякий раз через цикл само по себе не есть гуд и создаст некислую нагрузку. Намного проще (и логичнее) сделать один запрос к папке с сортировкой и записью полученных данных в переменную. Например:
$date = Get-Date
$data = ls | ? {!$_.PSIsContainer} | select @{
N='Exists';E={($date - $_.CreationTime).Days}
}, FullName | sort Exists
В итоге получим "таблицу" с количеством дней с момента создания файла и полным именем последнего (для более безопасного удаления). Далее из полученной коллекции останется исключить файлы, согласно требуемому критерию. Так, к примеру, для дней:
$days = 17
($data | ? {$_.Exists -le $days})[0]
По аналогии - недели и месяцы, единственно, что их придется перевести в количество дней (недели: ($date - $date.AddDays(-(7 * $NumberOfWeeks))).Days, месяцы: ($date - $date.AddMonths(-$NumberOfMonths)).Days).
Суть, полагаю, ясна.

etherlord
17-03-2016, 15:41
$days = 17
($data | ? {$_.Exists -le $days})[0] »
Тут таблица получится с файлами моложе 17 дней. И обрабатывать таблицу - все равно же цикл потребуется как я понимаю. Нужно брать файлы Старше Х и моложе Х-1, пропускать 1й, удалять остальные.
И, скажите пожалуйста, почему полный путь безопаснее получается?

greg zakharov
17-03-2016, 16:54
Тут таблица получится с файлами моложе 17 дней. И обрабатывать таблицу - все равно же цикл потребуется как я понимаю.Похоже, что Вы вообще ничего не понимаете или попросту не желаете понять. 17 здесь для примера (вообще, слово пример о чем-то сигнализирует для кого-то или это пустой звук?!), а цикл там и на кол не сдался. Если так и не дошло, то представляйте себе ФС как некую БД: оператор SELECT -eq командлет Select-Object (или его альяс select), оператор WHER -eq Where-Object (или его альяс ?), - недаром ведь намекалось на табличность. А вообще читайте PoSh'евский man до просветления, может тогда снизойдет озарение.

etherlord
17-03-2016, 23:54
17 здесь для примера »
я согласен что пример, но я не могу понять как обрабатывать файлы 17-дневной давнойсти, 18.. и т.д.
как я понимаю Ваш запрос вернет первый файл, которой младше 17 дней. , но как перебирать что-бы 1 файл из 1одного дня?




© OSzone.net 2001-2012