Компьютерный форум 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=348948)

epoddubniy 07-06-2021 15:08 2959646

Удалить файлы из каталога и подкаталогов старше даты Х но младше даты У
 
Здравствуйте!

Есть каталог "Dir".
В этом каталоге - подкаталоги "SubDir1, SubDir2, SubDir3...".
В подкаталогах файлы с датой создания начиная с лохматых времен, которые удалять пока нельзя, но и копировать - некуда.
В подкаталогах файлы создаются каждый день.
Как удалить файлы созданные позже 30.05.21, но раньше 04.05.21?

Помогите, пожалуйста.

Любой язык, WSH. CMD, Powershell

Спасибо!

DJ Mogarych 07-06-2021 15:40 2959648

Powershell:
Код:

dir d:\dir -File -Recurse |? {$_.CreationTime -lt ("04.05.21" -as [datetime]) -or $_.CreationTime -gt ("30.05.21" -as [datetime])} |del

Elven 07-06-2021 16:10 2959649

DJ Mogarych, можно сразу в метод:

Код:

(Get-ChildItem d:\dir -File -Recurse |? {$_.CreationTime -lt ("04.05.21" -as [datetime]) -and $_.CreationTime -gt ("30.05.21" -as [datetime])}).Delete()
И вроде бы у ТС было указано "но", т.о. не -or а -and, но тогда какой-то бред получается "раньше чем позже, но позже чем раньше"

DJ Mogarych 07-06-2021 16:32 2959652

Никакого бреда. "And" в данном случае - это файл должен быть создан и после одной даты и до другой одновременно, т. е., такой выборке не будет ничего соответствовать.

Поэтому выбираем файлы до одной даты ИЛИ после другой.

Elven 07-06-2021 16:40 2959654

DJ Mogarych, не буду спорить. Тем более, что да - в такую выборку ни один файл не попадет. Но мне вот что-то кажется что ТС даты местами перепутал.

epoddubniy 08-06-2021 18:41 2959738

Цитата:

Цитата Elven
DJ Mogarych, не буду спорить. Тем более, что да - в такую выборку ни один файл не попадет. Но мне вот что-то кажется что ТС даты местами перепутал. »

а ведь точно, перепутал...
вместо 04.06.21 написал 04.05.21

Код:

dir D:\backup_OS\ugo.FDB -File -Recurse |? {$_.CreationTime -lt ("26.04.21" -as [datetime]) -or $_.CreationTime -gt ("14.04.21" -as [datetime])} |del
DJ Mogarych, объясните пожалуйста, удалились все архивы и до 14.04.21 и после 26.04.21 и между 14.04-26.04 что я не так сделал? Скажите пожалуйста что означают -gt(это же - "раньше"?), -lt (это же - "later? позже?")

greg zakharov 08-06-2021 19:50 2959742

-gt и -lt - это операторы сравнения, означающие "больше" и " меньше" соответственно. На языке математики это будет выглядеть как > и < соответственно.
В вашем случае проще инвертировать даты в т.н. julian day и определить диапазон значений (с теорией множеств вы же знакомы, верно?), что упростит работу с датами, во-первых, а во-вторых, исключит вероятность ложных удалений.

DJ Mogarych 08-06-2021 21:18 2959751

-gt - greater than
-lt - less than

В данном случае вы указали удалить всё, что раньше 26 апреля и то, что позже 14 апреля. То есть, вообще всё.

Запускать скрипты, не вполне понимая, что они делают, это так себе идея.

greg zakharov 08-06-2021 23:03 2959766

Цитата:

Цитата DJ Mogarych
Запускать скрипты, не вполне понимая, что они делают, это так себе идея.

Наверное, следует создать тему, в которой нужно прописать CapsLock'ом для всех вопрошающих о необходимости использования параметра -WhatIf при тестах. Тему озаглавить "Золотые правила кодописателя".

Elven 09-06-2021 09:29 2959783

Уж сколько раз твердили миру,
Что без WhatIf'a жизнь вредна; но только всё не впрок,
И del в скрипте всегда отыщет уголок.
(с) не И.А. Крылов

epoddubniy 09-06-2021 16:19 2959824

Цитата:

Цитата greg zakharov
Наверное, следует создать тему, в которой нужно прописать CapsLock'ом для всех вопрошающих о необходимости использования параметра -WhatIf при тестах. Тему озаглавить "Золотые правила кодописателя". »

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

Цитата DJ Mogarych
Запускать скрипты, не вполне понимая, что они делают, это так себе идея. »

Не хотел обременять лишними расспросами, полагал, что понимаю, что делаю. Как оказалось - нет.
Цитата:

Цитата greg zakharov
в т.н. julian day и определить диапазон значений (с теорией множеств вы же знакомы, верно?) »

к сожалению, не знаком, буду гуглить
DJ Mogarych, скажите пожалуйста, каким образом видоизменить Ваш код, чтобы, например, при запуске в субботу удалялись файлы созданные в пн, вт, ср, чт?

greg zakharov 09-06-2021 17:32 2959837

Цитата:

Цитата epoddubniy
Сориентируйте пожалуйста, где можно подробно прочитать про этот механизм

Механизм - громко сказано, ибо оное всего-навсего т.н. общий параметр, а почерпнуть информацию о нём вы можете либо онлайн на сайте Microsoft, либо во "встроенной" справке. В целом же просто возьмите за правило добавлять в конце директив командлетов -WhatIf, например:
Код:

Remove-Item .\sucks.txt -WhatIf
Цитата:

Цитата Elven
Уж сколько раз твердили миру,
Что без WhatIf'a жизнь вредна; но только всё не впрок,
И del в скрипте всегда отыщет уголок.
(с) не И.А. Крылов

Elven, творчество Крылова - на 70 с лишком процентов вольный перевод Лафонтена, творчество которого в свою очередь на 80 с гаком - Эзоп. Вопрос: сколько процентов в вас от Эзопа?
Цитата:

Цитата epoddubniy
каким образом видоизменить Ваш код, чтобы, например, при запуске в субботу удалялись файлы созданные в пн, вт, ср, чт?

Сделать соответствующую выборку вестимо.

DJ Mogarych 09-06-2021 17:55 2959841

Код:

$t = Get-Date
dir D:\Dir -File -Recurse |? {$_.CreationTime -lt $t.Date.adddays(-1) -and $_.CreationTime -ge $t.Date.adddays(-5)} |del


Elven 09-06-2021 19:00 2959847

Цитата:

Цитата greg zakharov
сколько процентов в вас от Эзопа? »

Код:

$Esop = 1
$Lafonten =  $Esop * 0.8
$Krilov = $Lafonten * 0.7
$Elven = $Krilov * 0.9 #всего-то пару слов поменял...
Write-Host Esop / Elven = $Elven
-------------

Esop / Elven = 0,504

Ну, не то чтобы совсем, но и вот как-то так. 50,4% от Эзопа получается.

greg zakharov 09-06-2021 19:10 2959850

Elven, с учётом примерных данных, снимаю перед вами шляпу!

DJ Mogarych, видимо вы переутомились уже. Критерием выступают пн.-чт. включительно, следовательно:
Код:

(ls d:\dir -file -rec).Where{$_.CreationTime.DayOfWeek -in 1..4}
Также строятся и прочие "решето".

DJ Mogarych 09-06-2021 19:54 2959856

Нет, дорогой мой, не обольщайтесь.
Имелось в виду удаление всех файлов на этой неделе, кроме предыдущего дня, а не все понедельники-четверги.

Переутомились, видимо, вы, потому что .dayofweek даёт имя дня, а не номер. Номер даёт
Код:

$_.CreationTime.DayOfWeek.value__ -in 1..4

greg zakharov 09-06-2021 20:12 2959859

Цитата:

Цитата DJ Mogarych
Номер даёт...

Что в Core, что в пятом PowerShell DayOfWeek вполне себя самостоятельно "приводит" к целочисленному типу, так что моя запись корректна и верна - ложка дёгтя в вашу сторону, раз. Вторая ложка дёгтя - приведённый код является обобщением "решета" значений. Будьте так любезны, не сочтите за труд, заранее спасибо, перечитайте вышенаписанное: "также строятся прочие 'решето'". Если русский для вас неродной язык, поясняю: то безличное обобщение; обобщение подразумевает некую шаблонность, - но это уже из области толковых словарей.

DJ Mogarych 09-06-2021 22:29 2959871

Русский я знаю лучше вас, дорогуша.
Не сочтите за труд, бросьте общаться подобным образом с людьми.

greg zakharov 09-06-2021 22:51 2959872

Цитата:

Цитата DJ Mogarych
Русский я знаю лучше вас, дорогуша.

Вам видней. Только ваш оппонент гетеро, и подобные проявления знаков внимания ни к чему. Верю, что вы ещё встретите свою любовь.

epoddubniy 10-06-2021 14:37 2959940

DJ Mogarych, помогите пожалуйста, не удаляется
Заранее прошу прощения если опубликовал изображение не в том виде или не по правилам.


Elven 10-06-2021 15:06 2959945

замените del на write-host чтобы увидеть, что он таки находит нужные файлы.
вот этот вариант отрабатывает на раз, если есть файлы попадающие под фильтр.
Код:

$t = Get-Date
(Get-ChildItem -File -Recurse | Where-Object {$_.CreationTime -lt $t.Date.AddDays(-1) -and $_.CreationTime -ge $t.Date.AddDays(-4)}).Delete()


DJ Mogarych 10-06-2021 15:47 2959955

epoddubniy, дата изменения и дата создания необязательно совпадают.

Посмотрите, что у вас пишет
Код:

dir c:\test -file -recurse |select Name,CreationTime,LastWriteTime
Если вам нужно удалять по дате изменения, то замените в скрипте CreationTime на LastWriteTime.

megaloman 10-06-2021 16:07 2959957

Если:
- лохматые времена - это 2000 год и позже
- дата в системе отображается как дд.мм.гг или дд.мм.гггг
- и я правильно понимаю, что надо удалить файлы с 04.05.21<=дата изменения<=30.05.21
то:
Вот CMD
Код:

@Echo Off
        Set "BoxIn=Z:\Box_Arc"
        Set "Date1=04.05.21"
        Set "Date2=30.05.21"

        Set "D1=20%Date1:~-2%%Date1:~3,2%%Date1:~0,2%"
        Set "D2=20%Date2:~-2%%Date2:~3,2%%Date2:~0,2%"

        For /f "usebackq delims=" %%f In (`2^>nul Dir /B /A:-D /O:D /S "%BoxIn%\*.*"`) Do (
                Set "DD=%%~tf"
                Call :MyDel "%%f" %D1% %D2% %%DD%%
        )
Exit /B

:MyDel
        Set "DD=%4"
        Set "DD=20%DD:~-2%%DD:~3,2%%DD:~0,2%"
        If %2 LEQ %DD% If %DD% LEQ %3 Del %1
Exit /B

Идея решения: даты прекрасно можно сравнивать, если дату сконвертировать в число вида ггггммдд, тогда в этом случае не нужно инвертировать даты в т.н. julian day
если надо удалить файлы вне диапазона с 04.05.21<=дата изменения<=30.05.21
Код:

:MyDel
        Set "DD=%4"
        Set "DD=20%DD:~-2%%DD:~3,2%%DD:~0,2%"
        If %2 LEQ %DD% If %DD% LEQ %3 Exit /B
        Del %1
Exit /B


epoddubniy 11-06-2021 09:54 2960024

Цитата:

Цитата DJ Mogarych
Посмотрите, что у вас пишет »

DJ Mogarych, пишет вот это

Цитата:

Цитата megaloman
- дата в системе отображается как дд.мм.гг или дд.мм.гггг
- и я правильно понимаю, что надо удалить файлы с 04.05.21<=дата изменения<=30.05.21 »

дата отображается, как дд.мм.гггг
надо удалить файлы созданные в промежуток с 30.05.2021 по 04.06.2021 (первое условие)
надо удалить файлы созданные 2,3,4,5 дней назад, то есть при запуске скрипта в субботу удаляются файлы созданные в ЧТ,СР,ВТ,ПН (второе условие)
megaloman, скажите пожалуйста, как изменить Ваш код, чтобы он отработал по второму условию, то есть, при запуске скрипта в субботу удаляются файлы созданные в ЧТ,СР,ВТ,ПН

Цитата:

Цитата Elven
Код:
$t = Get-Date
(Get-ChildItem -File -Recurse | Where-Object {$_.CreationTime -lt $t.Date.AddDays(-1) -and $_.Creation »

перешел в каталог, выполнил код, файлы к сожалению не удалились

Elven 11-06-2021 10:32 2960029

тогда жду результатов выполнения вотэтоговот:
Код:

$t = Get-Date
$rl = Get-ChildItem -File -Recurse | Where-Object {$_.CreationTime -lt $t.Date.AddDays(-1) -and $_.CreationTime -ge $t.Date.AddDays(-4)}
if ($null -ne $rl) {
  Write-Host CreationTime in removing list:
  $rl | Select-Object CreationTime
  # $rl.Delete()
} else {
Write-Host Current time: $t
Get-ChildItem -File -Recurse | Select-Object CreationTime
}

Скриншоты сувать не обязательно, можно просто вывод обрамленный тегом code

megaloman 11-06-2021 10:55 2960032

Цитата:

Цитата epoddubniy
надо удалить файлы созданные 2,3,4,5 дней назад »

Увы, задача сводится к определению диапазона дат, а в CMD с этим туго.
Вот громоздкий CMD, который решает задачу. Работает как по Вашему первому, так и по второму условию
Код:

@Echo Off
        Set "BoxIn=Z:\Box_Arc"
        Call :Period 04.05.21 30.05.21

        Call :FromDate -5 %Date% "Date1"
        Call :FromDate -2 %Date% "Date2"
        Call :Period %Date1% %Date2%
Exit /B

:Period
        Set "Date1=%1"
        Set "Date2=%2"

        Set "D1=20%Date1:~-2%%Date1:~3,2%%Date1:~0,2%"
        Set "D2=20%Date2:~-2%%Date2:~3,2%%Date2:~0,2%"

        For /f "usebackq delims=" %%f In (`2^>nul Dir /B /A:-D /O:D /S "%BoxIn%\*.*"`) Do (
                Set "DD=%%~tf"
                Call :MyDel "%%f" %D1% %D2% %%DD%%
        )
Exit /B

:MyDel
        Set "DD=%4"
        Set "DD=20%DD:~-2%%DD:~3,2%%DD:~0,2%"
        If %2 LEQ %DD% If %DD% LEQ %3 Del %1
Exit /B

:FromDate

rem Пересчет даты на заданное кол-во дней
rem В первом аргументе +- дни
rem Во втором аргументе дата в формате dd.mm.yyyy
rem В третем аргументе имя переменной в кавычках где получим новую дату в формате dd.mm.yyyy

rem Заимствовано http://forum.oszone.net/thread-186889.html
rem вызов Call :FromNow %DeltaDay% %Date% "MyDate"
rem результат в перемменной %MyDate%

SetLocal
        Set "DT=%~2"
        Set yyyy=%DT:~-4%& set /a mm=100%DT:~3,2%%%100& set /a dd=100%DT:~,2%%%100
        Set /A JD=%~1+dd-32075+1461*(yyyy+4800+(mm-14)/12)/4+367*(mm-2-(mm-14)/12*12)/12-3*((yyyy+4900+(mm-14)/12)/100)/4
        Set /A L=JD+68569,N=4*L/146097,L=L-(146097*N+3)/4,I=4000*(L+1)/1461001
        Set /A L=L-1461*I/4+31,J=80*L/2447,K=L-2447*J/80,L=J/11
        Set /A J=J+2-12*L,I=100*(N-49)+I+L
        Set /A yyyy=I,mm=100+J,dd=100+K
EndLocal& Set "%~3=%dd:~-2%.%mm:~-2%.%yyyy%"
GoTo :Eof


epoddubniy 16-06-2021 09:17 2960378

Цитата:

Цитата Elven
тогда жду результатов выполнения вотэтоговот: »

Код:

PS C:\Users\Кубрин\Desktop> cd C:\test

PS C:\test> $t = Get-Date

PS C:\test> $rl = Get-ChildItem -File -Recurse | Where-Object {$_.CreationTime -lt $t.Date.AddDays(-1) -and $_.CreationTime -ge $t.Date.AddDays(-4)}


PS C:\test> if ($null -ne $rl) {
  Write-Host CreationTime in removing list:
  $rl | Select-Object CreationTime
  # $rl.Delete()
} else {
Write-Host Current time: $t
Get-ChildItem -File -Recurse | Select-Object CreationTime
}
Current time: 16.06.2021 9:13:34

CreationTime     
------------     
29.05.2021 14:19:49
02.06.2021 14:19:05
03.06.2021 14:18:46
28.05.2021 14:20:02
06.06.2021 14:18:03
05.06.2021 14:17:47
01.06.2021 14:19:25
04.06.2021 14:17:30
27.05.2021 14:20:11

Цитата:

Цитата megaloman
Увы, задача сводится к определению диапазона дат, а в CMD с этим туго. »

megaloman, правильно ли я понимаю, что
Код:

Call :Period 04.05.21 30.05.21
вот эту процедуру мне придется выполнять в любом случае?
Тогда - вопрос, могу ли я заменить 30.05.21 на переменную %date%?
И еще вопрос, можно ли каким-либо образом заранее объявить переменную, например, PeriodDateNachalo, значение которой бы определялось %date% минус 5 дней, чтобы в выражение
Код:

Call :Period 04.05.21 30.05.21
подставлялись значения переменных, а не ручной ввод?

Elven 16-06-2021 09:31 2960388

Цитата:

Цитата epoddubniy
29.05.2021 14:19:49
02.06.2021 14:19:05
03.06.2021 14:18:46
28.05.2021 14:20:02
06.06.2021 14:18:03
05.06.2021 14:17:47
01.06.2021 14:19:25
04.06.2021 14:17:30
27.05.2021 14:20:11 »

epoddubniy, ну и где тут файлы созданные с (-1) по (-4) дни?
если
Цитата:

Цитата epoddubniy
Current time: 16.06.2021 9:13:34 »

то CreationTime проверяется с 15.06.2021 9:13:34 по 11.06.2021 9:13:34
Ну и понятное дело ничего не удаляется, потому что ничего не попадает в выборку.

megaloman 16-06-2021 12:48 2960404

epoddubniy,
Цитата:

Цитата epoddubniy
правильно ли я понимаю, что
Call :Period 04.05.21 30.05.21
вот эту процедуру мне придется выполнять в любом случае? »

Цитата:

Цитата epoddubniy
надо удалить файлы созданные в промежуток с 30.05.2021 по 04.06.2021 (первое условие)
надо удалить файлы созданные 2,3,4,5 дней назад, то есть при запуске скрипта в субботу удаляются файлы созданные в ЧТ,СР,ВТ,ПН (второе условие) »

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


        Call :Period 04.05.21 30.05.21

        Call :FromDate -5 %Date% "Date1"
        Call :FromDate -2 %Date% "Date2"

echo  Date =%Date%
echo  Date1=%Date1%
echo  Date2=%Date2%

        Call :Period %Date1% %Date2%

Call :FromDate -5 %Date% "Date1"
в переменной %Date1% выдаётся дата, отстоящая от %Date% на -5 дней
Call :FromDate -2 %Date% "Date2"
в переменной %Date2% выдаётся дата, отстоящая от %Date% на -2 дней
Если сегодня 16.06.2021, то отладочные Echo выдадут
Date =16.06.2021
Date1=11.06.2021
Date2=14.06.2021
Соответственно, в процедуру Call :Period автоматом попадут даты, привязанные к сегодняшней дате.

epoddubniy 20-06-2021 21:30 2960615

Всем спасибо!


Время: 23:42.

Время: 23:42.
© OSzone.net 2001-