Ru-Board.club
← Вернуться в раздел «В помощь системному администратору»

» Написание скрипта для удаления файлов в папках c одним имене

Автор: reyst
Дата сообщения: 18.05.2005 10:27
Черт с ним с доступом - оставил на полный доступ - это особо не принципиально. Но появилась новая заморочка. Можно ли сделать так, чтобы те папки PostBox, в которых есть вложенная папка "InBox" не удалялись ...
Автор: evle
Дата сообщения: 18.05.2005 14:43
reyst
for /R <Путь к корню> %%i in (.) do echo %%~fi\ | find "\PostBox\" && if not exist ­%%~fi\InBox (RD /S /Q "%%~fi" && MD "%%~fi" && xcacls "%%~fi" /G Everyone:F /Y)
Что-то вроде этого. Как всегда не проверял. С доступом тоже можно сделать, но сложно. Говорят есть прога под названием SetACL, но у меня ее нет.
Автор: reyst
Дата сообщения: 19.05.2005 11:46
К сожалению не срабатывает - очищает все папки, в том числе и содержащие папки InBox

Добавлено:
может я не правильно выразился:
Сами папки InBox остаются - то, что и требуется, а вот их содержимое почему-то удаляется. Нужно, чтобы с папками PostBox, содержащих папку "InBox" вообще никаких действий не проводилось ...
Автор: reyst
Дата сообщения: 20.05.2005 14:27
evle
до финиша остался один шаг ...
если не трудно подскажи как побороть эту проблему
Автор: evle
Дата сообщения: 20.05.2005 15:21
reyst
Мысль такая: пропустить строку через еще один find "\PostBox\InBox\" и если не найдено (заюзать %ERRORLEVEL%), то удалять. Только надо похимичить будет. Сегодня - завтра подумаю, если не найдешь.
Второй вариант: Временно сделать эти папки только для чтения и/или скрытыми.
Вообще, стучись в аську или почту, подумаем вместе.
Автор: reyst
Дата сообщения: 23.05.2005 08:58
evle

Цитата:
Временно сделать эти папки только для чтения и/или скрытыми.


Вручную это сделать проблематично, получается, что нужно писать новый скрипт для поиска и изменения атрибутов ...
Автор: Felix
Дата сообщения: 23.05.2005 10:21
reyst
Давно наблюдаю за всеми мучениями, может мысль и не новая, но! кто мешает поставить Перл и написать полноценный скрипт для всевозможного колупания файлов и папок?
Автор: Alan Mon
Дата сообщения: 23.05.2005 10:33
reyst
Давай еще раз точно сформулируй задачу. А то я уже запутался, что тебе нужно. Файлы из папок InBox нужно удалять или нет?

Добавлено:
Felix

Цитата:
кто мешает поставить Перл и написать полноценный скрипт для всевозможного колупания файлов и папок?

Видимо только то, что ни я, ни reyst, ни evle не знаем Perl . Предложи свой скрипт.
А решить эту задачку исключительно средствами .cmd мне, например, просто интересно.

Автор: reyst
Дата сообщения: 23.05.2005 12:34
Alan Mon

С очисткой PostBox'ов я думаю разобрались. Тобишь скрипт находит все папки PostBox и "очищает" их путем удаления, создания и установления прав. Задача усложнилась тем, что:
папки PostBox, в составе которых есть папка "InBox" должны остаться нетронутыми, т.е. их не нужно очищать. Расшифровка: все папки (а не только InBox), которые находятся в этой папке PostBox и все файлы во вложенных папках должны остаться в том же состоянии.

После выполнения нового скрипта, разработанного ув. evle:

for /R <Путь к корню> %%i in (.) do echo %%~fi\ | find "\PostBox\" && if not exist %%~fi\InBox (RD /S /Q "%%~fi" && MD "%%~fi" && xcacls "%%~fi" /G Everyone:F /Y)

происходит следующее:
в папках PostBox, содеражащих папку "InBox", после выполнения скрипта вложенные папки остаются, что и требовуется, но содержимое вложенных папок удаляется ...
Автор: Alan Mon
Дата сообщения: 23.05.2005 13:12
reyst
Так как задача усложнилась и обросла дополнительными условиями, предлагаю разгрузить эту навороченную команду и вернуться к первому моему варианту, чуть-чуть его подправив:

Код: for /R <Путь к корню твоих папок> %%i in (.) do echo %%~fi\ | find "\PostBox\" && call :delet %%~fi
goto :end

:delet
echo %1\ | find "\InBox\" && goto :end
rd /S /Q "%1"
md "%1"
xcacls "%1" /G Everyone:F /Y

:end
Автор: evle
Дата сообщения: 23.05.2005 13:27
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;
Автор: reyst
Дата сообщения: 23.05.2005 15:32
[/b]Alan Mon[/b]

По Вашему скрипту папки "PostBox" по-прежнему удаляются несмотря на вложенные "InBox", поскольку остутсвует вложеный алгоритм поиска папки "InBox". Получается переменная пути %%fi (тобишь найденна папка "C:\Firma\IT\PostBox") анализируется в блоке elet на наличие в пути строки "InBox", которой ясное дело не будет по контексту алгоритма ....

evle
Если честно немного запутался - сначал мы ищем в пути папки строку "PostBox", потом в ней же "\PostBox\InBox\", а потом проверка на наличе \InBox - ???
В результате выполнения скрипта очищаются только папки InBox. Все папки PostBox, в том числе и со вложенными папками "InBox". не очищаются...
Функция exist определяет есть ли вложенная строка?
Автор: Felix
Дата сообщения: 23.05.2005 16:12

Цитата:

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

Именно то, что нужно
Автор: reyst
Дата сообщения: 24.05.2005 16:25
Я практически приблизился к решению этой задачи средствами cmd, используя уже созданные заготовки. Хочу уточнить значение строки

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

Означает ли это, что если в имени каталога присутсвует строка "\PostBox\", то переход на :end, иначе выполняется следующая команда. Т.е. && goto :end выполняется в случае удачного поиска строки "\PostBox\" или же это означает что-то другое?

Автор: Alan Mon
Дата сообщения: 24.05.2005 16:43
reyst

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

Это означает, что для ВСЕХ каталогов, начиная с пути, заданного строкой %1 будет выполнена команда echo ... и каждый раз, если в пути присутствует PostBox будет выполнен переход на :end
Автор: evle
Дата сообщения: 24.05.2005 17:25
Поскольку строчка действительно получилась длинноватой, пожалуй стоит перейти к варианту 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
Автор: reyst
Дата сообщения: 25.05.2005 14:45
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\" и соответсвенно не создает эту папку заново
Автор: evle
Дата сообщения: 25.05.2005 15:10
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
Автор: reyst
Дата сообщения: 03.06.2005 12:38
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. Просто я не совсем понимаю смысл символа && ...
Автор: Alan Mon
Дата сообщения: 03.06.2005 13:16
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
Автор: evle
Дата сообщения: 03.06.2005 15:00
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
Автор: reyst
Дата сообщения: 07.06.2005 15:25
evle
БЛЕСТЯЩЕ!!! Вот что значит инструмент в руках мастера - можно не то что вертолеты и самолеты, а и космические корабли строить


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

Остался последний штрих в решении этой задачи. Данный скрипт отрабатывает безотказно только на папках, с однословным названием - если в названии папки есть пробел, то скрипт в ней не срабтывет. Взял в кавычки "" все что только можно - не помогло ....
Автор: evle
Дата сообщения: 07.06.2005 17:15
C кавычками некоторая заминка. Я так и не понял, по какому правилу их расставлять. Если брать всё в кавычки, то cmd их не снимает при передаче параметров. Можно попробовать вот так:

Код: del /Q "%*\*.*"
del /Q /AH "%*\*.*"
for /D %%k in (%*\*.*) do (
findstr /I /c:"%%~nk" notdel || rd /S /Q "%%k"
Автор: reyst
Дата сообщения: 08.06.2005 11:24
К сожалению в этом варианте уже не работает, то что работало - не происходит очистка 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 за оказанную помощь

Автор: wers
Дата сообщения: 22.05.2006 17:21
Приветствую, сделал на 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
Автор: distance
Дата сообщения: 22.05.2006 19:12
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));
Автор: wers
Дата сообщения: 23.05.2006 09:09
distance
Извини, я пока чайник в программировании на windows shell. Твой кусочек не запускается, vbs выдает: "предполагается наличие окончания конструкции".
Предполагаю, что нужно первоначально записать что-то с функцией set, но вот что?
Автор: distance
Дата сообщения: 23.05.2006 13:26
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>

Страницы: 12

Предыдущая тема: Автоматизация администрирования. Скрипты на KIX


Форум Ru-Board.club — поднят 15-09-2016 числа. Цель - сохранить наследие старого Ru-Board, истории становления российского интернета. Сделано для людей.