none
Рекурсивное удаление RRS feed

  • Вопрос

  • Доброе время суток! необходимо рекурсивно удалять  файлы.
    Написал такой  скрипт:

            $Days_to_remove="10"
            $NowDate = Get-Date
            $LastWrite = $NowDate.AddDays(-$days_to_remove)
            $Files = get-childitem $backup_dest -recurse | Where-Object {$_.LastWriteTime -le "$LastWrite"}
                foreach ($File in $Files)
                    {
                        Remove-Item $backup_dest\$File
                    }

    Проблема возникла когда  появились, когда появились подпапки. Т.к. $File  возвращает только имя файла  из  любой  папки, то  удаление не проходит.


    Если сообщение было информативным, отметьте его как ответ. И нам приятно и сразу видно ответ на вопрос :-)

Ответы

  • Денис, а разве так не проще?..

    get-childitem $backup_dest -recurse | Where-Object {$_.LastWriteTime -le $LastWrite} | remove-item
    Спасибо моей жене Кате, Клевогину С.П., Козлову С.В., Муравлянникову Н.А., Никитину И.Г., Шапиро Л.В. за мои знания! :)
    • Помечено в качестве ответа Bakanov Denis 9 июня 2009 г. 7:28
    Отвечающий
  • Мое добавление на случай, если папки нужно сохранить, а удалить только файлы:

    $LastWrite = (Get-Date).AddDays(-10)
    get-childitem $backup_dest -recurse | Where-Object {-not $_.PSIsContainer -and $_.LastWriteTime -le $LastWrite} | remove-item -WhatIf
    Сазонов Илья http://www.itcommunity.ru/blogs/sie/
    • Предложено в качестве ответа Vadims PodansMVP 9 июня 2009 г. 8:31
    • Отменено предложение в качестве ответа Bakanov Denis 9 июня 2009 г. 8:46
    • Помечено в качестве ответа Bakanov Denis 9 июня 2009 г. 8:47
    Модератор
  • $c=@((Get-ChildItem "d:\for_test").Count)
     и что вы этим хотели получить? Вот так должно быть:
    $c=@(Get-ChildItem "d:\for_test").Count
    [тут могла быть ваша реклама] http://www.sysadmins.lv
    • Помечено в качестве ответа Bakanov Denis 15 июня 2009 г. 12:51
    15 июня 2009 г. 12:21

Все ответы

  • Денис, а разве так не проще?..

    get-childitem $backup_dest -recurse | Where-Object {$_.LastWriteTime -le $LastWrite} | remove-item
    Спасибо моей жене Кате, Клевогину С.П., Козлову С.В., Муравлянникову Н.А., Никитину И.Г., Шапиро Л.В. за мои знания! :)
    • Помечено в качестве ответа Bakanov Denis 9 июня 2009 г. 7:28
    Отвечающий
  • Чет ступил. Конвейер, блин.
     Как бы еще это  дело прикрутить к папкам  ...
    Если сообщение было информативным, отметьте его как ответ. И нам приятно и сразу видно ответ на вопрос :-)
  • Мое добавление на случай, если папки нужно сохранить, а удалить только файлы:

    $LastWrite = (Get-Date).AddDays(-10)
    get-childitem $backup_dest -recurse | Where-Object {-not $_.PSIsContainer -and $_.LastWriteTime -le $LastWrite} | remove-item -WhatIf
    Сазонов Илья http://www.itcommunity.ru/blogs/sie/
    • Предложено в качестве ответа Vadims PodansMVP 9 июня 2009 г. 8:31
    • Отменено предложение в качестве ответа Bakanov Denis 9 июня 2009 г. 8:46
    • Помечено в качестве ответа Bakanov Denis 9 июня 2009 г. 8:47
    Модератор
  • Хотелось бы в данном случае удалять пустые папки потом. Как осуществить ?
    Если сообщение было информативным, отметьте его как ответ. И нам приятно и сразу видно ответ на вопрос :-)
  • Признак папки $_.PSIsContainer
    Поэтому удаление папок  будет такое:

    get-childitem $backup_dest -recurse | Where-Object {$_.PSIsContainer } | remove-item -WhatIf
    Сазонов Илья http://www.itcommunity.ru/blogs/sie/
    9 июня 2009 г. 13:22
    Модератор
  • это понятно, как проверить , что папка пустая ?
    Если сообщение было информативным, отметьте его как ответ. И нам приятно и сразу видно ответ на вопрос :-)
    10 июня 2009 г. 4:55
  • это понятно, как проверить , что папка пустая ?
    Если сообщение было информативным, отметьте его как ответ. И нам приятно и сразу видно ответ на вопрос :-)

    Можно так: {$_.GetFiles().Count -eq 0}

    Спасибо моей жене Кате, Клевогину С.П., Козлову С.В., Муравлянникову Н.А., Никитину И.Г., Шапиро Л.В. за мои знания! :)
    10 июня 2009 г. 7:11
    Отвечающий
  • Кстать нашел ответ на свой  скрипт:
            $Days_to_remove="10"
            $NowDate = Get-Date
            $LastWrite = $NowDate.AddDays(-$days_to_remove)
            $Files = get-childitem $backup_dest -recurse | Where-Object {$_.LastWriteTime -le "$LastWrite"}
                foreach ($File in $Files)
                    {
                        Remove-Item $File.FullName
                    }

    По поводу  Рекурсивного  удаления папок.

    $files=get-childitem "d:\for_test\del" -recurse | Where-Object {$_.PSIsContainer } | Where-object {$_.GetFiles().Count -eq 0}
    Foreach    ($Fil in $files)
        {
            Remove-Item $Fil.Fullname
        }

    Суть в том, что возвращает все подряд и начинает удалять с  корневых папок. Т.е. не смотрит в  подпапки сначала,а потом уровнем выше.

    Как  бы сделать, что б  он  шел с самой  глубокой папки, а только потом  поднимался  на уровень выше? и так  для всех папок
    Если сообщение было информативным, отметьте его как ответ. И нам приятно и сразу видно ответ на вопрос :-)
    11 июня 2009 г. 7:28
  • Вам надо удалять файлы старше 10 дней, а еще вы хотите удалить пустые папки?
    Вам придется сделать это за два шага: сначала файлы, потом папки. Иначе скрипт у вас неоправдано усложниться.


    Сазонов Илья http://www.itcommunity.ru/blogs/sie/
    11 июня 2009 г. 10:00
    Модератор
  • Вот ссылка на рекурсивную функцию, которая удаляет пустые папки http://softwaresalariman.blogspot.com/2008/01/prune-directories-with-powershell.html


    Сазонов Илья http://www.itcommunity.ru/blogs/sie/
    11 июня 2009 г. 10:15
    Модератор
  • именно так и собираюсь поступить. Ссылку посмотрим.
    Если сообщение было информативным, отметьте его как ответ. И нам приятно и сразу видно ответ на вопрос :-)
    11 июня 2009 г. 12:38
  • Кстать тут  заметил странное поведение. Пишу пробный скрипт:

    $per= (Get-ChildItem "d:\For_test\test").Count
    write-host $per

    В ответ получаю:
    Если больше одного файла в папке  - все нормально считает
    А если один файл, то он его не видит. Почему ?
    Если сообщение было информативным, отметьте его как ответ. И нам приятно и сразу видно ответ на вопрос :-)
    11 июня 2009 г. 13:34
  • Потому что если файл один, то Get-ChildItem "d:\For_test\test" возвращает не массив, а один элемент!
    Если хотите всегда получать массив, заключите оператор в конструкцию @()


    Сазонов Илья http://www.itcommunity.ru/blogs/sie/
    • Помечено в качестве ответа Bakanov Denis 15 июня 2009 г. 8:09
    • Снята пометка об ответе Bakanov Denis 15 июня 2009 г. 12:17
    15 июня 2009 г. 7:29
    Модератор
  • Пишу , к примеру, $c=@((Get-ChildItem "d:\for_test").Count)

    результат - тот же
    Если сообщение было информативным, отметьте его как ответ. И нам приятно и сразу видно ответ на вопрос :-)
    15 июня 2009 г. 12:18
  • $c=@((Get-ChildItem "d:\for_test").Count)
     и что вы этим хотели получить? Вот так должно быть:
    $c=@(Get-ChildItem "d:\for_test").Count
    [тут могла быть ваша реклама] http://www.sysadmins.lv
    • Помечено в качестве ответа Bakanov Denis 15 июня 2009 г. 12:51
    15 июня 2009 г. 12:21