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

kasab 14-08-2019 23:19 2884058

Удаление файла по дате в Имени
 
Привет
Нужна помощь в создании скрипта, который удалял бы файлы, по дате а имени (формата название_yyyymmdd.bd)
Суть в том, что бы оставлять 3-5 самых свежих файла (по дате в названии) остальные удалять


перепробовал совмещать различные варианты, но для примера в CMD\BAT не хочет считывать имя

Код:

@echo off
SetLocal EnableExtensions

:: папка, с файлами вида yyyymmdd для удаления
set "Folder=C:\temp\test"& set "rs=bd"
 pushd "%Folder%"

For /F "delims=" %%a in ('forfiles /d -3 /m "*%DATE:-4%%DATE:~3,2%%DATE:~6,2%.bd"') do if not defined "%%a" echo del /f /q "%rs%%%a"
exit /b

это не обязательно должен быть cmd/bat
главное, что бы работало
спасибо

Iska 15-08-2019 00:06 2884063

Цитата:

Цитата kasab
формата название_yyyymmdd.bd »

«название_» у всех файлов одинаковое?

Код:

@echo off
setlocal enableextensions enabledelayedexpansion

set sSourceFolder=C:\Мои проекты\0271\Source

for /f "usebackq skip=5 delims=" %%i in (
        `2^>nul dir /b  /a:-d /o:-n "%sSourceFolder%\название_*.bd"`
) do echo del /f /q "%sSourceFolder%\%%~i"

endlocal
exit /b 0

Для реального удаления уберите echo.

Charg 15-08-2019 00:41 2884071

А зачем ориентироваться на дату записанную в названии если у каждого файла и так есть аттрибуты времени? Тот же CreationTime
На Powershell будет выглядеть как-то так:

Код:

$path = "C:\test\*"
$allfiles = Get-ChildItem -Path $path -Force -File -Include *.bd | select * | Sort-Object -Descending CreationTime
$allfiles[5..($allfiles.Count - 1)] | Remove-Item -WhatIf

Нюансы:
1. Путь должен заканчиваться на \* чтобы корректно отрабатывал фильтр -Include *.bd (это ведь расширение файла, да? Если нет то подставь своё расширение), чтобы в свою очередь работать только с нужными файлами и пропускать скрытые системные файлы, если вдруг они есть.
2. -WhatIf в конце позволяет безболезненно посмотреть что сделает код - увидишь какие файлы будут удалены этим кодом без их фактического удаления.
3. Возможно понадобиться -Force там же, в конце. Зависит от наличия прав.
4. Если когда-нибудь придется изменить количество оставляемых файлов - $allfiles[5..($allfiles.Count - 1)] фильтрует элементы с пятого по последний. Т.к. нумерация элементов в массиве начинается с 0 - приходится отнимать 1 от количества элементов чтобы получить номер последнего ($allfiles.Count - 1), в данном случае для 10 файлов - последний номер 9. Соответственно фильтр $allfiles[5..9] удаляет элементы с пятого по девятый, оставляя элементы с 0го по 4ый (итого 5)

Iska 15-08-2019 03:32 2884075

Цитата:

Цитата Charg
А зачем ориентироваться на дату записанную в названии если у каждого файла и так есть аттрибуты времени? »

Например, потому, что дата/время в названии файла могут и не иметь отношения к датам создания/последней модификации файла.

kasab 15-08-2019 05:44 2884078

Цитата:

Цитата Iska
«название_» у всех файлов одинаковое? »

Да, начало названия всегда одинаково, спасибо, потестирую)

Цитата:

Цитата Charg
А зачем ориентироваться на дату записанную в названии если у каждого файла и так есть аттрибуты времени? Тот же CreationTime »

Это копируемый файл базы, у него всегда одинаковый параметр даты создания, потому добавляется в имя дата копирования

Busla 15-08-2019 11:54 2884137

kasab, я когда-то колхозил с прямо противоположной стороны: в имени бэкапа использовал не дату, а день недели - сама собой получалась авторотация с периодом в неделю. Хотя, конечно, негибко - лёгким движением руки переопределить период не получится (но так ли часто меняются такие настройки).

Цитата:

Цитата kasab
Это копируемый файл базы, у него всегда одинаковый параметр даты создания »

подсказка: у файла несколько атрибутов времени: дата создания и дата изменения

Charg 15-08-2019 12:09 2884142

Цитата:

Цитата Iska
Например, потому, что дата/время в названии файла могут и не иметь отношения к датам создания/последней модификации файла. »

Если это бэкап (а это бэкап) то крайне маловероятно что в названии даты что-то кроме даты актуальности этого бэкапа. Не дата создания так дата модификации.

Цитата:

Цитата kasab
Это копируемый файл базы, у него всегда одинаковый параметр даты создания, потому добавляется в имя дата копирования »

Тогда почему бы не оперировать датой последней модификации файла? Всё равно эта дата будет равняться дате актуальности БД.

Iska 15-08-2019 12:37 2884146

Charg, дату/время в имена файлов, особенно резервных копий, добавляют совсем не случайно. Ибо упомянутые Вами атрибуты файла внезапно — смертны.

Charg 15-08-2019 12:41 2884147

Цитата:

Цитата Iska
Ибо упомянутые Вами атрибуты файла внезапно — смертны. »

Каким образом?

megaloman 15-08-2019 12:43 2884148

Iska, А зачем двойной цикл? Можно так:
Код:

@Echo Off
        Set "BoxArc=Z:\Box_ARC"
        Set "Mask=Название бэкапа базы_20??????.bd"
        Set /A NSave=5
        FOR /F "usebackq skip=%Nsave% delims=" %%f IN (`2^>nul Dir "%BoxArc%\%Mask%" /B /A:-D /O:-N`) DO Echo Del "%BoxArc%\%%f"
Exit /B

Имхо, еще лучше так:
Код:

@Echo Off
        Call :DelData "Z:\Box_ARC\Название бэкапа базы_20??????.bd" 5
Exit /B

:DelData
        FOR /F "usebackq skip=%2 delims=" %%f IN (`2^>nul Dir %1 /B /A:-D /O:-N`) DO Echo Del "%~dp1%%f"
Exit /B

Особенно если надо обработать бэкапы нескольких баз
Цитата:

Цитата Iska
Для реального удаления уберите echo. »


Iska 15-08-2019 12:54 2884152

Цитата:

Цитата Charg
Каким образом? »

CreationTime замещается на текущее при копировании файла. LastWriteTime замещается на текущее при любой модификации содержимого и сохранении.

Цитата:

Цитата megaloman
Iska, А зачем двойной цикл? »

megaloman, не пойму, где у меня двойной цикл?!

megaloman 15-08-2019 13:00 2884156

Iska, Простите великодушно, спешка, нет у Вас двойного цикла, а жена гонит на охоту на базар за мамонтом на обед ... :)

Charg 15-08-2019 13:07 2884160

Цитата:

Цитата Iska
LastWriteTime замещается на текущее при любой модификации содержимого и сохранении. »

Если файл бд меняется - меняется и дата актуальности бэкапа, разве нет?

Iska 16-08-2019 14:23 2884349

megaloman, спасибо, ясно, сочувствую.

Цитата:

Цитата Charg
Если файл бд меняется - меняется и дата актуальности бэкапа, разве нет? »

Charg, а причём тут это?

Нам нужно удержать значение некоей конкретной даты/времени привязанным к конкретному файлу. И дата создания, и дата последней модификации файла для этого не годятся (даже если это именно одно из них по сути), поскольку оригинальные даты в любой момент могут быть утрачены неловким или бессознательным движением руки, в то время, как потребное значение даты/времени, тупо вставленное в имя файла, для утраты требует исключительно сознательных усилий.

Charg 16-08-2019 15:05 2884357

Цитата:

Цитата Iska
а причём тут это? »

А при том что если существующий бэкап сделанный в дату N был изменён - он перестал быть бэкапом на дату N, несмотря на то что имя файла свидетельствует что это всё еще бэкап на момент даты N.
Да, чисто технически, есть возможность изменить файл так чтобы дата изменения обновилась а сам бэкап остался рабочим и валидным - но стоит ли предполагать что над бэкапом произвели именно такие действия? Вопрос не совсем однозначный но, имхо, ответ - нет, бэкап перестал быть бэкапом, во всяком случае на момент той даты которая написана в его имени.

Iska 16-08-2019 15:27 2884360

Цитата:

Цитата Charg
А при том что если существующий бэкап сделанный в дату N был изменён - он перестал быть бэкапом на дату N, несмотря на то что имя файла свидетельствует что это всё еще бэкап на момент даты N. »

Коллега, сие как-то противоречит тому, о чём я говорю? Нет.

А чтобы быть уверенным в его валидности — тут уже другие методы нужны: блокировка от изменений, контрольные суммы и прочее.

kasab 17-08-2019 10:17 2884424

Цитата megaloman:
Имхо, еще лучше так:

Код:

@Echo Off
    Call :DelData "Z:\Box_ARC\Название бэкапа базы_20??????.bd" 5
Exit /B
:DelData
    FOR /F "usebackq skip=%2 delims=" %%f IN (`2^>nul Dir %1 /B /A:-D /O:-N`) DO Echo Del "%~dp1%%f"
Exit /B

Особенно если надо обработать бэкапы нескольких баз »
Цитата Iska:

Код:

@echo off
setlocal enableextensions enabledelayedexpansion
set sSourceFolder=C:\Мои проекты\0271\Source
for /f "usebackq skip=5 delims=" %%i in (
    `2^>nul dir /b /a:-d /o:-n "%sSourceFolder%\название_*.bd"`
) do echo del /f /q "%sSourceFolder%\%%~i"
endlocal
exit /b 0

Для реального удаления уберите echo. »
Оба Варианта работают, Спасибо

По датам в атрибутах Создания: Сам бекап настраивал другой пользователь, грубо говоря, но разных серверах стоит батник, который раз в сутки копирует на один сервер в соответствующую папку файл базы, сохраняя на конечном сервере с датой текущей в имени. И каким то образом, дата создания и изменения остаются у всех "Бекапов" одинаковыми, и не меняются. Если бы они менялись, то на основе даты изменения и создавал бы батник, но тут то и был зарыт камень преткновения и задачу поставили смотреть именно в дату в имени файла.


Время: 12:00.

Время: 12:00.
© OSzone.net 2001-