Перейти из форума на сайт.

НовостиФайловые архивы
ПоискАктивные темыТоп лист
ПравилаКто в on-line?
Вход Забыли пароль? Первый раз на этом сайте? Регистрация
Компьютерный форум Ru.Board » Компьютеры » В помощь системному администратору » Написание скрипта для удаления файлов в папках c одним имене

Модерирует : lynx, Crash_Master, dg, emx, ShriEkeR

 Версия для печати • ПодписатьсяДобавить в закладки
Страницы: 1 2 3

Открыть новую тему     Написать ответ в эту тему

evle



1 + int rand(100);
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
reyst
Вот, собрал такое:
for /R <Путь к корню> %%i in (.) do echo %%~fi\ | find /I "\PostBox\" && echo %%~fi\ | find /I /N "\PostBox\InBox\" && if not exist %%~fi\InBox (RD /S /Q "%%~fi" && MD "%%~fi" && xcacls "%%~fi"  /G Everyone:F /Y)  
Может и сработает. (На всякий случай прикрутил /I к find, вдруг папки не в том регистре названы)
В следующий раз постарайся задачу формулировать сразу целиком, чтобы дополнительные шурупами не привинчивать.
Alan Mon
16:33 23-05-2005
Цитата:
Видимо только то, что ни я, ни reyst, ни evle не знаем Perl

Perl знаю плохо, зато знаю того, кто знает хорошо. Сейчас дал ему эту задачку. Придет ответ - запосчу сюда.
 
Добавлено:
Кто там рекламировал Perl?
Вот на Перле:

Код:
use File::Find;
@ARGV = (".") unless @ARGV;find sub {if (-d && $_ eq "PostBox" && !(-d "$_/InBox")) {chdir "PostBox";system "del *\.* ";chdir "../"}}, @ARGV;

 


----------
For every complex problem, there is a solution that is simple, neat, and wrong.

Всего записей: 2110 | Зарегистр. 03-02-2005 | Отправлено: 14:27 23-05-2005 | Исправлено: evle, 15:52 23-05-2005
reyst

Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
[/b]Alan Mon[/b]  
 
По Вашему скрипту папки "PostBox" по-прежнему удаляются несмотря на вложенные "InBox", поскольку остутсвует вложеный алгоритм поиска папки "InBox". Получается переменная пути %%fi (тобишь найденна папка "C:\Firma\IT\PostBox") анализируется в блоке elet на наличие в пути строки "InBox", которой ясное дело не будет по контексту алгоритма ....
 
evle
Если честно немного запутался - сначал мы ищем в пути папки строку "PostBox", потом в ней же "\PostBox\InBox\", а потом проверка на наличе \InBox - ???
В результате выполнения скрипта очищаются только папки InBox. Все папки PostBox, в том числе и со вложенными папками "InBox". не очищаются...
Функция exist определяет есть ли вложенная строка?

Всего записей: 247 | Зарегистр. 29-11-2004 | Отправлено: 16:32 23-05-2005
Felix



Advanced Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору

Цитата:
 
Код:
use File::Find;
@ARGV = (".") unless @ARGV;find sub {if (-d && $_ eq "PostBox" && !(-d "$_/InBox")) {chdir "PostBox";system "del *\.* ";chdir "../"}}, @ARGV;
 

Именно то, что нужно

----------
In My Opinion!

Всего записей: 965 | Зарегистр. 20-01-2002 | Отправлено: 17:12 23-05-2005 | Исправлено: Felix, 17:15 23-05-2005
reyst

Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Я практически приблизился к решению этой задачи средствами cmd, используя уже созданные заготовки. Хочу уточнить значение строки
 
for /R "%1" %%i in (.) do echo %%~fi\ | find "\PostBox\" && goto :end  
 
Означает ли это, что если в имени каталога присутсвует строка "\PostBox\", то переход на  :end, иначе выполняется следующая команда. Т.е. && goto :end  выполняется в случае удачного поиска строки "\PostBox\" или же это означает что-то другое?
 

Всего записей: 247 | Зарегистр. 29-11-2004 | Отправлено: 17:25 24-05-2005
Alan Mon

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
reyst

Цитата:
for /R "%1" %%i in (.) do echo %%~fi\ | find "\PostBox\" && goto :end  

Это означает, что для ВСЕХ каталогов, начиная с пути, заданного строкой %1 будет выполнена команда echo ... и каждый раз, если в пути присутствует PostBox будет выполнен переход на :end

----------
Ребята, давайте жить дружно. Кот Леопольд

Всего записей: 1116 | Зарегистр. 22-07-2004 | Отправлено: 17:43 24-05-2005
evle



1 + int rand(100);
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Поскольку строчка действительно получилась длинноватой, пожалуй стоит перейти к варианту Alan Mon  
Правда я его модифицировал вдребезги. :-)
ИМХО, так проще получается.
 

Код:
for /R <Путь к корню твоих папок> %%i in (.) do if exist %%~fi\PostBox\ && if not exist %%~fi\PostBox\InBox call :delet %%~fi\Postbox
goto :end  
   
:delet  
del /S /Q %1\*.*
del /S /Q /AH %1\*.*
for /d %k in (%1\*.*) do rd %k
:end
 
 
На всякий случай принцип работы:
находим каталоги, в которых есть папка PostBox, но нет PostBox\InBox.
Для каждого такого каталога PostBox проводим следующие операции:  

  1. Удаление файлов из всех папок.
  2. Удаление скрытых файлов из всех папок. (опционально)
  3. Удаление всех папок.

Еще и  с правами париться не придется, поскольку сами каталоги не удаляются.
Потести.

----------
For every complex problem, there is a solution that is simple, neat, and wrong.

Всего записей: 2110 | Зарегистр. 03-02-2005 | Отправлено: 18:25 24-05-2005
reyst

Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
evle
Выдает сообщение && was unexpected at this time
 
Я решил (как кажется на первый взгляд) упростить задачу к следующей:
во всех всех папках PostBox удалять все кроме папок InBox и OutBox с их содержимым.
 
for /R c:\Farmak %%i in (.) do echo %%~fi\ | find /I "\PostBox\" && call elet %%~fi  
goto :end  
   
elet  
for /R "%1" %%i in (.) do echo %%~fi\ | find "\InBox\" && goto :end  
for /R "%1" %%i in (.) do echo %%~fi\ | find "\OutBox\" && goto :end  
rd /S /Q "%1"  
for /R "%1" %%i in (.) do echo %%~fi\ | find "\PostBox\" && goto :end - этой строкой  
производится проверка на наличие в пути создаваемой папки строки \PostBox\. Ключевой тут есть закрывающий символ "\", т.е. если это сама папка PostBox (символ "\" буде отсутсвовать), то ее нужно вновь создавать, если же это папка вложенная в папку PostBox, то создавать ее не нужно.
 
md "%1"  
xcacls "%1" /G Everyone:F /Y  
:end  
 
Все было бы хорошо, только почему то команда find как-то находит в самих папках Postbox (к примеру c:\Firma\Otdel\Postbox ) строку "\PostBox\" и соответсвенно  не создает эту папку заново

Всего записей: 247 | Зарегистр. 29-11-2004 | Отправлено: 15:45 25-05-2005
evle



1 + int rand(100);
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
reyst
20:45 25-05-2005
Цитата:
Выдает сообщение && was unexpected at this time  

Ага, зря я это там написал.

Цитата:
Я решил (как кажется на первый взгляд) упростить задачу к следующей:  

Ну ты нагородил :-)
Цитата:
почему то команда find как-то находит в самих папках Postbox  

Еще бы оно их там не находило:

Цитата:
 echo %%~fi\  

В общем, поколдовал я немного, получил такой вариант:

Код:
for /R  %%i in (.) do if exist %%~fi\PostBox\ if not exist %%~fi\PostBox\InBox call :delet "%%~fi\Postbox"
goto :end    
   
:delet  
del /S /Q "%1\*.*"
del /S /Q /AH "%1\*.*"
for /d %%k in (%1\*.*) do rd /S /Q "%%k"
:end
 
Для разнообразия даже потестил. :-) У меня все работает.
Поправил потенциальный баг с кавычками (без них некоторые вещи не удалялись).

----------
For every complex problem, there is a solution that is simple, neat, and wrong.

Всего записей: 2110 | Зарегистр. 03-02-2005 | Отправлено: 16:10 25-05-2005
reyst

Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
evle
Еще раз благодарю за оказанную помощь
Поскольку в очередной раз от руководства поступила новая идея по поводу организации структуры папок и их очистки и с целью разобраться до конца на будущее, обращаюсь опять за помощью
Задача состоит в том, чтобы полностью чистить папки PostBox, кроме вложенных папок InBox и OutBox, если таковые имеются. Тобишь если папка PostBox не содержит папку InBox или OutBox, то мы просто ее удаляем, создаем заново и задем права, если же папка PostBox содержит одну (или обе) из папок InBox и OutBox, то удаляются все файлы PostBox\*.*, все вложенные папки с файлами, кроме папок InBox или OutBox со своими файлами.  У меня удалось реализовать все кроме удаления самих файлов PostBox\*.*. Использую я для этого команды del /S /Q "%1\*.*" ,del /S /Q /AH "%1\*.*" , но у меня проблема в самом алгоритме. Я хотел бы уточнить саму конструкцию строки:
for /R c:\Temp %%i in (.) do echo %%~fi\ | find /I "\PostBox" && call elet %%~fi -
 
как можно ее преобразовать так, чтобы если строка "\PostBox\" найдена, то call elet , а если не найдена, то call :nofind. Просто я не совсем понимаю смысл символа && ...

Всего записей: 247 | Зарегистр. 29-11-2004 | Отправлено: 13:38 03-06-2005
Alan Mon

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
reyst

Цитата:
Просто я не совсем понимаю смысл символа &&  

Этот символ обозначает, что команда, стоящая от него справа будет выполнена только если команда, стоящая слева завершилась успешно, т.е. errorlevel=0.
 
Тебе теперь по смыслу нужно реализовать конструкцию if ... else ... В одной строке это вряд ли сделаешь. Так что придется ее еще укорачивать. что-то типа этого:

Код:
for /R c:\Temp %%i in (.) do call :find "%%~fi\"
goto :end
 
:find
echo %1 | find /i "\PostBox\"
if errorlevel 1 call :nofind else call :delete
goto :end
 
:nofind
...
goto :end
 
:delete
...
 
:end

 
PS По-моему задача настолько усложнилась, что впору переходить на Perl или WSH. Уж больно некрасиво на cmd получается. А некрасивые самолеты нелетают :)

----------
Ребята, давайте жить дружно. Кот Леопольд

Всего записей: 1116 | Зарегистр. 22-07-2004 | Отправлено: 14:16 03-06-2005 | Исправлено: Alan Mon, 14:21 03-06-2005
evle



1 + int rand(100);
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
reyst
Про && можно прочитать во встроенной справке в главе "Общие сведения о командной оболочке" (в WinXP ее можно открыть так: mk:@MSITStore:C:\WINDOWS\Help\ntcmds.chm::/ntcmds_shelloverview.htm)
Если коротко, то этот символ означает выполнение следующей команды только в том случае, если предыдущая команда выполнена успешно (вернула 0), но лучше почитай тот раздел, там еще много интересного.
По поводу алгоритма: я не очень понял, зачем нужно что-то вызывать, если ничего строка не найдена. ведь в этом случае папку нужно просто пропустить. Вообще, ты привел не очень удачный алгоритм. Незачем разбивать задачу на два случая (есть InBox и нет InBox).
Поскольку папка, которую не надо удалять, уже не одна, то это уже список. Пусть хранится во внешнем файле.
Подход такой: находим папки PostBox, удаляем в них все файлы, пробегаем по папкам и если папка не из списка, то удаляем ее.

Код:
 
for /R  %%i in (.) do if exist %%~fi\PostBox\ call elet %%~fi\Postbox
goto :end    
   
elet  
del /Q %1\*.*
del /Q /AH "%1\*.*"  
for /D %%k in (%1\*.*) do (
findstr /I /c:"%%~nk" notdel || rd /S /Q %%k
)
:end  
 

Рядом с батником должен лежать файл "notdel" со списком папок, которые не надо удалять, каждое имя с новой строки. В данном случае файл будет выглядеть вот так:

Цитата:
 
InBox
OutBox
 

Alan Mon

Цитата:
PS По-моему задача настолько усложнилась, что впору переходить на Perl или WSH. Уж больно некрасиво на cmd получается. А некрасивые самолеты нелетают

А мы вертолет строим - они летают.
Я приводил код на перле, там еще веселее, к тому же там все равно вызываются стандртные команды. На WSH, конечно, можно перейти, но что-то лень. По поводу красоты: о вкусах не спорят. Мне лично решение через CMD нравится, да и ничего сложного в задаче нет.

----------
For every complex problem, there is a solution that is simple, neat, and wrong.

Всего записей: 2110 | Зарегистр. 03-02-2005 | Отправлено: 16:00 03-06-2005
reyst

Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
evle
БЛЕСТЯЩЕ!!!  Вот что значит инструмент в руках мастера - можно не то что вертолеты и самолеты, а и космические корабли строить

 
Используя новый алгоритм и новые средства cmd, evle удалось достичь тот же результат, что и предыдущим способ, что говорит о широких возможностях cmd!
 
Остался последний штрих в решении этой задачи. Данный скрипт отрабатывает безотказно только на папках, с однословным названием - если в названии папки есть пробел, то скрипт в ней не срабтывет. Взял в кавычки "" все что только можно - не помогло ....

Всего записей: 247 | Зарегистр. 29-11-2004 | Отправлено: 16:25 07-06-2005
evle



1 + int rand(100);
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
C кавычками некоторая заминка. Я так и не понял, по какому правилу их расставлять. Если брать всё в кавычки, то cmd их не снимает при передаче параметров. Можно попробовать вот так:

Код:
del /Q "%*\*.*"
del /Q /AH "%*\*.*"  
for /D %%k in (%*\*.*) do (  
findstr /I /c:"%%~nk" notdel || rd /S /Q "%%k"
 
Но есть большие сомнения, что сработает.  
Нормальное решение сам хотел бы увидеть.

Всего записей: 2110 | Зарегистр. 03-02-2005 | Отправлено: 18:15 07-06-2005
reyst

Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
К сожалению в этом варианте уже не работает, то что работало - не происходит очистка PostBox уже в однословных папках
 
Добавлено:
Есть КОНТАКТ!!!
Вот скрипт, который делает все, что нужно.
 
for /R С:\Firma %%i in (.) do call :ffind "%%~fi"  
goto :end  
 
:ffind
echo %1 | find /i "\PostBox\" && goto :end  
echo %1 | find /i "\PostBox" && goto elete
goto :end  
 
elete  
del /F /Q %1\*.*
del /F /Q /AH %1\*.*
 
for /R %1 %%i in (.) do call :box "%%~fi"  
goto :end
 
:box  
echo %1 | find /i "\InBox" && goto :end  
echo %1 | find /i "\OutBox" && goto :end
echo %1 | find /i "\PostBox\" && goto :rrd
goto :end  
 
:rrd  
rd /S /Q %1
 
:end  
 
Возможно не совсем рациональный вариант, но главное рабочий и как видно не используется утилита xcacls для раздачи прав. Выполняется очистка всех папок PostBox, кроме вложенных папок InBox и OutBox. Все таки cmd это сила!!!
 
Добавлено:
Благодарю evle и Alan Mon за оказанную помощь  


Всего записей: 247 | Зарегистр. 29-11-2004 | Отправлено: 12:24 08-06-2005
wers

Newbie
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Приветствую, сделал на WSH, а он работает только с явными путями! При использовании символьных переменных ничего не удаляется. В чем беда? В данном примере удаляются все мп3 с логического пути %HOMEDRIVE%\%HOMEPATH%. Совсем запутался, что указывать в функции GetFolder - FSO или WshShell?
 
Вот она:

Код:
 
Set WshShell = CreateObject("WScript.Shell")
Set objEnv = WshShell.Environment("Process")
Set FSO = CreateObject("Scripting.FileSystemObject")
 
sDIR = objEnv("HOMEDRIVE")+objEnv("HOMEPATH")
sEXT = "mp3"
 
Function GetFolder(sFOLDER)
  On Error Resume Next
  Set GetFolder = FSO.GetFolder(sFOLDER)
  If Err.Number <> 0 Then
    Wscript.Echo "Error connecting to folder: " & sFOLDER & _
       VBlf & "[" & Err.Number & "] " & Err.Description
    Wscript.Quit Err.Number
  End If
End Function
 
Sub DelFile(sFILE)
  On Error Resume Next
  FSO.DeleteFile sFILE, True
  If Err.Number <> 0 Then
    Wscript.Echo "Error deleting file: " & sFILE
  End If
End Sub
 
Sub GoSubFolders (objDIR)
  If objDIR <> objEnv("HOMEDRIVE")+objEnv("HOMEPATH") Then
    MainSub objDIR
    For Each eFolder in objDIR.SubFolders
      GoSubFolders eFolder
    Next
  End If
End Sub
 
 
Set objDIR = GetFolder(sDIR)
GoSubFolders objDIR
 
Sub MainSub (objDIR)
  For Each efile in objDIR.Files
    fEXT = FSO.GetExtensionName(efile.Path)
    If LCase(fEXT) = LCase(sEXT) Then
      DelFile efile
    End If
  Next
End Sub
 

Всего записей: 24 | Зарегистр. 15-07-2005 | Отправлено: 18:21 22-05-2006
distance

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
wers
GetFolder - это функция FSO
 
переменные в строке я заменял при помощи следующей функции:
(правда у меня предпологался синтаскис вида ${VAR_NAME}, а не %VAR_NAME%. Сие, впрочем, легко исправляется)
 

Код:
 
var shell = new ActiveXObject("WScript.Shell");
var env = shell.Environment("Process");
 
var s = "${HOMEDRIVE}${HOMEPATH}";
 
function Expand(s)
{
    return (s.replace(/\$\{([\w_]+[\w\d_]*)\}/g,
    function($0,$1)
    {
        var tmp = env($1);
        if (tmp == "")
            throw new Error("invalid environment variable " + $1);
        return (tmp.replace(/\\/g, "/"));
    }));
}
WScript.Echo(Expand(s));
 

 
результат:
C:/Documents and Settings/distance

Всего записей: 878 | Зарегистр. 28-03-2004 | Отправлено: 20:12 22-05-2006
wers

Newbie
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
distance
 Извини, я пока чайник в программировании на windows shell. Твой кусочек не запускается, vbs выдает: "предполагается наличие окончания конструкции".
 Предполагаю, что нужно первоначально записать что-то с функцией set, но вот что?

Всего записей: 24 | Зарегистр. 15-07-2005 | Отправлено: 10:09 23-05-2006
distance

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
wers
 
я не использую vbscript. Это фрагмент кода на jscript. Соответственно его нужно сохранить в файл с расширением js и тогда можно запускать.
можно комбинировать vbs и js скрипты, если использовать файл специального формата wsf (windows script file). Он выглядит примерно так:
 

Код:
 
<package>
<job>
<!-- так можно подключать другие файлы, как vbs, так и js -->
<script language="VBScript" src="fragment1.vbs"/>
<script language="JScript" src="fragment2.js"/>
 
<script language="JScript">
 
WScript.Echo("hello!");
 
</script>
</job>
</package>
 

 
запускать так же: cscript code.wsf или wscript code.wsf

Всего записей: 878 | Зарегистр. 28-03-2004 | Отправлено: 14:26 23-05-2006
Открыть новую тему     Написать ответ в эту тему

Страницы: 1 2 3

Компьютерный форум Ru.Board » Компьютеры » В помощь системному администратору » Написание скрипта для удаления файлов в папках c одним имене


Реклама на форуме Ru.Board.

Powered by Ikonboard "v2.1.7b" © 2000 Ikonboard.com
Modified by Ru.B0ard
© Ru.B0ard 2000-2025

LiteCoin: LgY72v35StJhV2xbt8CpxbQ9gFY6jwZ67r

Рейтинг.ru