Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   AutoIt (http://forum.oszone.net/forumdisplay.php?f=103)
-   -   [решено] Поиск каталогов (http://forum.oszone.net/showthread.php?t=250008)

TERMINAL 26-12-2012 13:24 2053759

Поиск каталогов
 
Здравствуйте ! Погуглив так и не нашёл ответа или примера как возможно найти папку 5DEL во всех подкаталогах папки TEST, глубина папки TEST неизвестна, и удалить все найденные каталоги 5DEL.
Заранее спс.

Creat0R 26-12-2012 13:54 2053789

Цитата:

Цитата TERMINAL
Погуглив так и не нашёл ответа или примера »

поиск папки autoit

А также есть уже тема на форуме.

TERMINAL 26-12-2012 17:18 2053896

Creat0R, Как бы нашёл скрипт
читать дальше »
Global $Stack[50], $Stack1[50]

$Text = ""
FileFindNextFirst("C:\WINDOWS")
While 1
$tempname = FileFindNext('',2,2)
If $tempname = "" Then ExitLoop
$Text &= $tempname & @CRLF
WEnd

FileFindNextFirst("C:\WINDOWS")
While 1
$tempname = FileFindNext('',0,1)
If $tempname = "" Then ExitLoop
$Text &= $tempname & @CRLF
WEnd

MsgBox(4096, '', $Text)

Func FileFindNextFirst($FindCat)
$Stack[0] = 1
$Stack1[1] = $FindCat
$Stack[1] = FileFindFirstFile($FindCat & "\*.*")
Return $Stack[1]
EndFunc ;==>FileFindNextFirst

;$mode=0 - файлы
;$mode=1 - типы файлов
;$mode=2 - каталоги
;$Level= от 1 до 49
Func FileFindNext($type = 'log', $mode = 0, $Level=49)
While 1
$file = FileFindNextFile($Stack[$Stack[0]])
If @error Then
FileClose($Stack[$Stack[0]])
If $Stack[0] = 1 Then
Return ""
Else
$Stack[0] -= 1
ContinueLoop
EndIf
Else
If StringInStr(FileGetAttrib($Stack1[$Stack[0]] & "\" & $file), "D") > 0 Then
If $Stack[0] = $Level Then ContinueLoop
$Stack[0] += 1
$Stack1[$Stack[0]] = $Stack1[$Stack[0] - 1] & "\" & $file
$Stack[$Stack[0]] = FileFindFirstFile($Stack1[$Stack[0]] & "\*.*")
If $mode=2 Then
Return $Stack1[$Stack[0]]
Else
ContinueLoop
EndIf
Else
If $mode=2 Then ContinueLoop
If $mode=1 Then
If StringRight($Stack1[$Stack[0]] & "\" & $file, 4)<>'.'&$type Then
ContinueLoop
Else
Return $Stack1[$Stack[0]] & "\" & $file
EndIf
Else
Return $Stack1[$Stack[0]] & "\" & $file
EndIf
EndIf
EndIf
WEnd
EndFunc ;==>FileFindNext

можно переделать и будет поиск каталогов, но не могу добиться глубины поиска папок в каталоге.

Creat0R 26-12-2012 18:24 2053947

Цитата:

Цитата TERMINAL
нашёл скрипт »

Который нужно заключать в тег кода.

Цитата:

Цитата TERMINAL
не могу добиться глубины поиска папок в каталоге »

А по ссылке перейти не судьба? :)

TERMINAL 27-12-2012 10:42 2054347

Creat0R, Судьбу испытывал и переходил по ссылке, но там же опять поиск файлов, мне файлы не нужны-нужны сами папки
PHP код:

#include <Array.au3>

$aReturn _FileSearch(@WindowsDir"File\....$"0)

_ArrayDisplay($aReturn)

Func _FileSearch($sPath$sRegExp_FileMask$iCaseSense=0)
    
Local $iPID$sStdOutRead$aRet$sFindStr$sCaseStr

    
If Not $iCaseSense Then $sCaseStr ' /I'
    
$sFindStr 'Dir "' $sPath '" /S /B | FindStr' $sCaseStr ' /R "' $sRegExp_FileMask '"'

    
$iPID Run(@ComSpec ' /C ' $sFindStr, @SystemDir, @SW_HIDE2)

    While 
1
        $sStdOutRead 
&= StdoutRead($iPID)
        If @
error <> 0 Then ExitLoop
    WEnd

    $aRet 
StringSplit(StringStripCR(StringStripWS($sStdOutRead3)), @LF)
    Return 
SetError(@error0$aRet)
EndFunc 

Реализовать поиск папок я так и не смог.

Creat0R 27-12-2012 15:44 2054530

Цитата:

Цитата TERMINAL
там же опять поиск файлов, мне файлы не нужны-нужны сами папки »

Там и поиск папок:

Код:

$aReturn = _FileSearch('C:\Test', "\\5DEL$", 0)
_ArrayDisplay($aReturn)

Ещё вот тут есть более новая версия данного метода:

Код:

#include <Array.au3>

$aReturn = _FileDirList('C:\Test', "5DEL", 2)
_ArrayDisplay($aReturn)

Func _FileDirList($sPath, $sFileMask = "*", $iFlag = 0, $iSubDir = 1, $iSort = 0)
    Local $sOutBin, $sOut, $aOut, $aMasks, $sRead, $hDir, $sAttrib, $sFiles

    If Not StringInStr(FileGetAttrib($sPath), "D") Then
        Return SetError(1, 0, 0)
    EndIf

    If $iSubDir = 1 Then
        $sAttrib &= ' /S'
    EndIf

    If $iSort = 1 Then
        $sAttrib &= ' /O:N'
    EndIf

    Switch $iFlag
        Case 1
            $sAttrib &= ' /A-D'
        Case 2
            $sAttrib &= ' /AD'
        Case Else
            $sAttrib &= ' /A'
    EndSwitch

    $sOut = StringToBinary('0' & @CRLF, 2)
    $sPath = StringRegExpReplace($sPath, '\\+$', '')
    $sFileMask = StringRegExpReplace($sFileMask, '^;+|;+$', '')
    $sFileMask = StringRegExpReplace($sFileMask, ';{2,}', ';')
    $aMasks = StringSplit($sFileMask, ';')

    For $i = 1 To $aMasks[0]
        If StringStripWS($aMasks[$i], 8) = "" Then
            ContinueLoop
        EndIf

        $sFiles &= '"' & $sPath & '\' & $aMasks[$i] & '"'

        If $i < $aMasks[0] Then
            $sFiles &= ';'
        EndIf
    Next

    $hDir = Run(@ComSpec & ' /U /C DIR ' & $sFiles & ' /B' & $sAttrib, @SystemDir, @SW_HIDE, 6)

    While ProcessExists($hDir)
        $sRead = StdoutRead($hDir, False, True)

        If @error Then
            ExitLoop
        EndIf

        If $sRead <> "" Then
            $sOut &= $sRead
        EndIf
    Wend

    $aOut = StringRegExp(BinaryToString($sOut, 2), '[^\r\n]+', 3)

    If @error Or UBound($aOut) < 2 Then
        Return SetError(2, 0, 0)
    EndIf

    $aOut[0] = UBound($aOut)-1
    Return $aOut
EndFunc


-TRM- 11-01-2013 11:50 2064057

Creat0R, А как-то возможно на диске найти пустые каталоги или подкаталоги и удалить их?
И такой ещё вопросик- если известен путь С:\TEST02\Downloads\TMP\VIA\FORCED\5x86\new\viamraid64.cat
то как возможно получить из него путь С:\TEST02\Downloads\TMP\VIA\FORCED\5x86\new ? (т.е. без самого файла)

madmasles 11-01-2013 12:33 2064091

Цитата:

Цитата -TRM-
А как-то возможно на диске найти пустые каталоги или подкаталоги и удалить их? »

Попробуйте примерно так.
Код:

#include <Array.au3>
#include <WinAPIEx.au3>

Global $aRet, $iSuccess = 0, $iError = 0

$aRet = _FileDirList(@HomeDrive, '*', 2)
_ArrayDisplay($aRet)
For $i = 1 To $aRet[0]
    If _WinAPI_PathIsDirectoryEmpty($aRet[$i]) Then
        If DirRemove($aRet[$i]) Then
            $iSuccess += 1
        Else
            $iError += 1
        EndIf
    EndIf
Next

MsgBox(64, 'Info', StringFormat('All:\t%i\nDel:\t%i\nError:\t%i', $aRet[0], $iSuccess, $iError))

Func _FileDirList($sPath, $sFileMask = "*", $iFlag = 0, $iSubDir = 1, $iSort = 0)
    Local $sOutBin, $sOut, $aOut, $aMasks, $sRead, $hDir, $sAttrib, $sFiles

    If Not StringInStr(FileGetAttrib($sPath), "D") Then
        Return SetError(1, 0, 0)
    EndIf

    If $iSubDir = 1 Then
        $sAttrib &= ' /S'
    EndIf

    If $iSort = 1 Then
        $sAttrib &= ' /O:N'
    EndIf

    Switch $iFlag
        Case 1
            $sAttrib &= ' /A-D'
        Case 2
            $sAttrib &= ' /AD'
        Case Else
            $sAttrib &= ' /A'
    EndSwitch

    $sOut = StringToBinary('0' & @CRLF, 2)
    $sPath = StringRegExpReplace($sPath, '\\+$', '')
    $sFileMask = StringRegExpReplace($sFileMask, '^;+|;+$', '')
    $sFileMask = StringRegExpReplace($sFileMask, ';{2,}', ';')
    $aMasks = StringSplit($sFileMask, ';')

    For $i = 1 To $aMasks[0]
        If StringStripWS($aMasks[$i], 8) = "" Then
            ContinueLoop
        EndIf

        $sFiles &= '"' & $sPath & '\' & $aMasks[$i] & '"'

        If $i < $aMasks[0] Then
            $sFiles &= ';'
        EndIf
    Next

    $hDir = Run(@ComSpec & ' /U /C DIR ' & $sFiles & ' /B' & $sAttrib, @SystemDir, @SW_HIDE, 6)

    While ProcessExists($hDir)
        $sRead = StdoutRead($hDir, False, True)

        If @error Then
            ExitLoop
        EndIf

        If $sRead <> "" Then
            $sOut &= $sRead
        EndIf
    WEnd

    $aOut = StringRegExp(BinaryToString($sOut, 2), '[^\r\n]+', 3)

    If @error Or UBound($aOut) < 2 Then
        Return SetError(2, 0, 0)
    EndIf

    $aOut[0] = UBound($aOut) - 1
    Return $aOut
EndFunc  ;==>_FileDirList

WinAPIEx.au3

AZJIO 11-01-2013 17:58 2064447

-TRM-,
_FO_SearchEmptyFolders

Цитата:

Цитата -TRM-
(т.е. без самого файла) »

_FO_PathSplit или регулярное выражение
Код:

StringRegExpReplace($sPath, '^(.*)\\.*$', '\1')

madmasles 11-01-2013 20:07 2064533

Цитата:

Цитата -TRM-
как возможно получить из него путь С:\TEST02\Downloads\TMP\VIA\FORCED\5x86\new ? (т.е. без самого файла) »

Или так.
Код:

$sPath = @ScriptFullPath
ConsoleWrite($sPath & @LF)
ConsoleWrite(StringRegExpReplace($sPath, '\\[^\\]*$', '') & @LF)

Взято отсюда: Деление пути к файлу на части

-TRM- 29-01-2013 11:13 2077480

madmasles, В функции
Цитата:

Func _FileDirList($sPath, $sFileMask = "*", $iFlag = 0, $iSubDir = 1, $iSort = 0)
Local $sOutBin, $sOut, $aOut, $aMasks, $sRead, $hDir, $sAttrib, $sFiles

If Not StringInStr(FileGetAttrib($sPath), "D") Then
Return SetError(1, 0, 0)
EndIf

If $iSubDir = 1 Then
$sAttrib &= ' /S'
EndIf

If $iSort = 1 Then
$sAttrib &= ' /O:N'
EndIf

Switch $iFlag
Case 1
$sAttrib &= ' /A-D'
Case 2
$sAttrib &= ' /AD'
Case Else
$sAttrib &= ' /A'
EndSwitch

$sOut = StringToBinary('0' & @CRLF, 2)
$sPath = StringRegExpReplace($sPath, '\\+$', '')
$sFileMask = StringRegExpReplace($sFileMask, '^;+|;+$', '')
$sFileMask = StringRegExpReplace($sFileMask, ';{2,}', ';')
$aMasks = StringSplit($sFileMask, ';')

For $i = 1 To $aMasks[0]
If StringStripWS($aMasks[$i], 8) = "" Then
ContinueLoop
EndIf

$sFiles &= '"' & $sPath & '\' & $aMasks[$i] & '"'

If $i < $aMasks[0] Then
$sFiles &= ';'
EndIf
Next

$hDir = Run(@ComSpec & ' /U /C DIR ' & $sFiles & ' /B' & $sAttrib, @SystemDir, @SW_HIDE, 6)

While ProcessExists($hDir)
$sRead = StdoutRead($hDir, False, True)

If @error Then
ExitLoop
EndIf

If $sRead <> "" Then
$sOut &= $sRead
EndIf
WEnd

$aOut = StringRegExp(BinaryToString($sOut, 2), '[^\r\n]+', 3)

If @error Or UBound($aOut) < 2 Then
Return SetError(2, 0, 0)
EndIf


$aOut[0] = UBound($aOut) - 1
Return $aOut
EndFunc ;==>_FileDirList
выделенное жирным, иногда вылетает ошибка
Error: Subscript used with non-Array variable. Как возможно предотвратить ошибку ? Return 0 ?

AZJIO 29-01-2013 11:35 2077494

-TRM-, использовать проверенную функцию пару постов выше, которую я уже пол-года использую в синхронизаторе файлов. После синхронизации имеет место появление пустых каталогов в виду удаления файлов, пришлось сделать поиск и удаление пустых каталогов. Пользуюсь вроде полгода, ни одного вылета.

-TRM- 29-01-2013 11:59 2077509

AZJIO, Я так понял Вы предлагаете использовать функцию _FO_SearchEmptyFolders ?!
Дело в том, что в функции,madmasles, которую предложил madmasles, папки тоже находятся, но проблема ещё и в другом: Если путь С:\Papka1\Papka2\Papka3\Papka4\Papka5 и в ней получается пустая папка Papka5 и в папках С:\Papka1\Papka2\Papka3\Papka4 тоже ничего нет, то функция удаляет только Papka5, а не весь путь С:\Papka1\Papka2\Papka3\Papka4\Papka5, поэтому приходиться в цикл кидать и проверять один путь несколько раз. А у Вас как в этой функции дело обстоит?

AZJIO 29-01-2013 12:24 2077525

-TRM-, а у нас два флага, удалять только совсем пустые каталоги и удалять каталог который может содержать сколько угодно пустых каталогов.
Цитата:

$iType [необязательный] (0,1) определяет, совсем пустые папки или разрешить каталог c пустыми папками, не добавляя вложенных
0 - папка может содержать пустые папки, не добавляя последние к списку (по умолчанию)
1 - папки пусты совсем
Тебе нужен 0.

-TRM- 02-02-2013 11:45 2080718

AZJIO, А как правильно понять выражение &=
Цитата:

Func __FO_SearchEmptyFolders1($sPath)
Local $sFolderList = '', $sFile, $s = FileFindFirstFile($sPath & '*')
If $s = -1 Then Return $sPath & @CRLF
While 1
$sFile = FileFindNextFile($s)
If @error Then ExitLoop
If @extended Then
$sFolderList &= __FO_SearchEmptyFolders1($sPath & $sFile & '\')
EndIf
WEnd
FileClose($s)
Return $sFolderList
EndFunc ;==>__FO_SearchEmptyFolders1
Это не зацикливание функции (одна в одной) ? И как понять выражение $iFill += 1 ?

Где нужно вставить команду удаления папки ? Ведь мне выводится уже полный список путей пустых папок, а не по одному пути.

kaster 02-02-2013 12:00 2080728

Цитата:

Цитата -TRM-
как правильно понять выражение &= »

Код:

$a &= 'something';
$a = $a & 'something'

Цитата:

Цитата -TRM-
как понять выражение $iFill += 1 ? »

Код:

$a += 1
$a = $a + 1


-TRM- 02-02-2013 12:20 2080741

AZJIO,
Цитата:

Примечания ..: Основная цель функции - последующее удаление пустых папок по найденному списку
Где нужно вставить команду удаления папки ? Ведь мне выводится уже полный список путей пустых папок, а не по одному пути-что-то разобраться не могу.

AZJIO 03-02-2013 05:01 2081364

-TRM-, Вот пример:

Код:

#include <Array.au3>
#include <FileOperations.au3>

$timer = TimerInit() ; таймер для скорости поиска
$aFolderList = _FO_SearchEmptyFolders(@WindowsDir) ; путь для примера поиска, НЕ СЛЕДУЕТ УДАЛЯТЬ в нём пустые папки
_ArrayDisplay($aFolderList, 'Время : ' & Round(TimerDiff($timer) / 1000, 2) & ' сек', -1, 0, '', '|', '№|Пустые папки') ; просмотр найденных пустыых папок

If MsgBox(4 + 262144, 'Сообщения', 'Удалить пустые папки ?') = 6 Then ; если ответ равен 6, что значить "Да", тогда
    $err = '' ; переменная для лога ошибок
    For $i = 1 To $aFolderList[0] ; цикл удаления папок
        If Not FileRecycle($aFolderList[$i]) Then ; если не удалось переместить в корзину, тогда
            If Not (FileSetAttrib($aFolderList[$i], '-RST') And FileRecycle($aFolderList[$i])) Then ; если не удалось снять атрибуты и переместить в корзину, тогда
                $err &= $aFolderList[$i] & @CRLF ; пишем лог
            EndIf
        EndIf
    Next
    If
$err Then MsgBox(0, 'Лог ошибок', $err) ; если лог ошибок не пустой, то смотрим его
EndIf

; FileRecycle($aFolderList[$i]) ; удаление в корзину
; DirRemove($aFolderList[$i], 1) ; удаление навсегда

1. UDF пишется не для того чтобы в него что-то вписывали. Всё что надо в него вписать передаётся через параметры, иначе весь смысл UDF пропадает.
2. Я вот подумал, а что если у вложенной пустой папки атрибут только чтение? Тогда думаю папку невозможно удалить, если используется поиск с ключом 0, то есть надо получить именно папки которые пусты совсем, тогда есть гарантия что при неудалении атрибуты будут сняты, чтобы удалить.

Цитата:

Цитата -TRM-
Это не зацикливание функции (одна в одной) ? »

это зацикливание и называется рекурсией. Глубина рекурсии не превышает 123 (количество максимально возможных вложений папок)

-TRM- 04-02-2013 16:36 2082342

AZJIO, Выскакивет
For $i = 1 To $aFolderList[0]
For $i = 1 To $aFolderList^ ERROR
Какого ?, никак понять не могу, папка не содержит пустые папки и на ней затык
Вот эта папка

AZJIO 04-02-2013 17:53 2082403

-TRM-, У тебя папка не содержит пустых папок. После вызова _FO_SearchEmptyFolders забыл добавить строку:
Код:

If @error Then Exit
Ну разве догадаться не можешь, если нет массива то и цикл отработать не сможет.
Твой архив не качал, пока некогда.

-TRM- 04-02-2013 18:11 2082424

AZJIO, спс, помогло.

-TRM- 05-02-2013 11:54 2082876

AZJIO, понимаю что не по теме, помоги плз ещё разобраться с функцией StringRegExp (тяжело что-то мне даётся) или может здесь другая функция нужна...
Есть слово Video_AMD_Notebook_13012 из трёх составляющих (Video, AMD, Notebook), вот мне из него нужно вытянуть эти три составляющие без цифр и без нижнего прочерка, но составляющие слова могут быть разные (от одной составляющей-USB_13002 и выше). Заранее спс.

Creat0R 05-02-2013 23:25 2083340

Цитата:

Цитата -TRM-
понимаю что не по теме »

Понимание не означает что можно нарушать правила.
Даже наоборот, это ещё больше усугубляет ситуацию, ты как бы признаёшь что понимаешь неправильность своих действии, и всё равно их делаешь.

Думаю тема себя исчерпала, помечено как Решено.


Время: 19:26.

Время: 19:26.
© OSzone.net 2001-