Что нового

[Файловая система] Проверка на наличие строки, перемещение файла содержащего её

SVD

Новичок
Сообщения
9
Репутация
2
Приветствую русское комьюнити замечательного скриптового языка :smile:
Версия AutoIt: v3.3.6.1

Описание: Имеется директория в которой имеются под директории, необходимо проверить наличие во всех папках файлов .txt, если файлы имеются - проверка первой строки каждого файла на наличие последовательности символов - при чем последовательность не строго определенная - проще говоря в каждом таком файле в первой строке написано время - нужно чтобы скрипт при виде времени в промежутке между 10:30 и 11:30 - перемещал этот файл в другую директорию создавая в ней точно такую же папку в которой он находился в исходной директории(а если папка уже есть, просто перемещал в нее). Затем после проверки и перемещении всех подходящих файлов, все оставшиеся скрипт переносил в третью деррикторию.

Примечания: Короче говоря скрипт для сортировки файлов. Проверять необходимо только первую сточку в файле. Буду очень признателен любой помощи.
 
Автор
S

SVD

Новичок
Сообщения
9
Репутация
2
Понимаю, нахлебников никто не любит :smile: пришел тут понимаешь, зарегистрировался и сделайте все за него :smile: -- на самом деле это не так, я сам имею (правда очень не большой) опыт работы с языком автоит, но его на самом деле очень мало... возможности и времени элементарно заняться углубленным изучение просто нет... всвязи с чем и пришел на форум...
На самом деле меня интересует больше всего два момента - можно ли средствами автоит реализовать:
1) Проверка первой строки на наличие инфы о времени в промежутке между 10:30 и 11:30
2) Перемещение соответствующего файла в другую директорию с созданием в ней директории в которой файл находился изначально
Подскажите пожалуйста как это можно реализовать или хотябы какими функциями, дальше уж сам допилю, постараюсь по крайней мере :smile:
 

Garrett

Модератор
Локальный модератор
Сообщения
3,999
Репутация
967
SVD
Где-то так. Попробуйте.
Код:
Dim $iMinTime = '10:30'
Dim $iMaxTime = '11:30'
Dim $sDirSource = 'C:\1'
Dim $sDirDestin = 'MyDir'

$aFile = _FileSearch($sDirSource, "*.txt")

For $i = 1 To UBound($aFile) -1

	$sLine = FileReadLine($aFile[$i])
	$aTime = StringRegExp($sLine, '(\d{2}):(\d{2})', 1)
	$nTime = Number($aTime[0] & $aTime[1])
	
	If $nTime > 1030 And $nTime < 1130 Then
		$sDestination = StringRegExpReplace($aFile[$i], '(\w:\\)(.*)', '$1' & $sDirDestin & '\\$2')
		FileCopy($aFile[$i], $sDestination, 9)
	EndIf
	
Next


;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; $iFlag = 0 - Файлы и папки (по умолчанию)
; $iFlag = 1 - Только файлы
; $iFlag = 2 - Только папки
;
; Source function http://forum.oszone.net/post-1339621.html#post1339621
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Func _FileSearch($sPath, $sFileMask, $iFlag = 0)
    Local $sOutBin, $sOut, $aOut, $sRead, $hDir, $sAttrib
    
    Switch $iFlag
        Case 1
            $sAttrib = ' /A-D'
        Case 2 
            $sAttrib = ' /AD'
        Case Else 
            $sAttrib = ' /A'
    EndSwitch
    
    $sOut = StringToBinary('0' & @CRLF, 2)
    $aMasks = StringSplit($sFileMask, ';')
    
    For $i = 1 To $aMasks[0]
        $hDir = Run(@ComSpec & ' /U /C DIR "' & $sPath & '\' & $aMasks[$i] & '" /S /B' & $sAttrib, @SystemDir, @SW_HIDE, 6)
        
        While 1
            $sRead = StdoutRead($hDir, False, True)
            
            If @error Then
                ExitLoop
            EndIf
            
            If $sRead <> "" Then
                $sOut &= $sRead
            EndIf
        Wend
    Next
    
    $aOut = StringRegExp(BinaryToString($sOut, 2), '[^\r\n]+', 3)
    
    If @error Then
        Return SetError(1)
    EndIf
    
    $aOut[0] = UBound($aOut)-1
    Return $aOut
EndFunc
 
Автор
S

SVD

Новичок
Сообщения
9
Репутация
2
Garrett
Спасибо огромное, все замечательно работает :smile: Только я упустил нюанс когда составлял первый пост -- формат времени не 10:30 и 11:30 а 10:30:00 и 11:30:00 - тоесть к отсортированным файлам попадают файлы с временем скажем 2:11:27 или 8:10:56 - если этот момент подправить вообще шик будет :smile:
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
Garrett,
В функцию _FileSearch() лучше добавить:
Код:
;...
If StringRight($sPath, 1) == '\' Then ;нужно, если $sPath - диск (например C:\)
	$sPath = StringTrimRight($sPath, 1)
EndIf
Switch $iFlag
;...
Без этих строк у меня в корне диска не ищет.
 

Garrett

Модератор
Локальный модератор
Сообщения
3,999
Репутация
967
SVD
Замените строки в коде выше:
Код:
$aTime = StringRegExp($sLine, '(\d{2}):(\d{2})', 1)
$nTime = Number($aTime[0] & $aTime[1])

на
Код:
$aTime = StringRegExp($sLine, '(\d{2}):(\d{2}):(\d{2})', 1)
$nTime = Number($aTime[0] & $aTime[1] & $aTime[2])



Добавлено:
Сообщение автоматически объединено:

Код:
Dim $iMinTime = 103000
Dim $iMaxTime = 113000
Dim $sDirSource = 'C:\Dir'
Dim $sDirDestin = 'MyDir'

$aFile = _FileSearch($sDirSource, "*.txt")

For $i = 1 To UBound($aFile) -1

	$sLine = FileReadLine($aFile[$i])
	$aTime = StringRegExp($sLine, '(\d{2}):(\d{2}):(\d{2})', 1)

	If IsArray($aTime) Then
		$nTime = Number($aTime[0] & $aTime[1] & $aTime[2])
		
		If $nTime > $iMinTime And $nTime < $iMaxTime Then
			$sDestination = StringRegExpReplace($aFile[$i], '(\w:\\)(.*)', '$1' & $sDirDestin & '\\$2')
			FileCopy($aFile[$i], $sDestination, 9)
			ConsoleWrite($sDestination &  @CRLF)
		EndIf
	EndIf
Next


;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; $iFlag = 0 - Файлы и папки (по умолчанию)
; $iFlag = 1 - Только файлы
; $iFlag = 2 - Только папки
;
; Source function http://forum.oszone.net/post-1339621.html#post1339621
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Func _FileSearch($sPath, $sFileMask, $iFlag = 0)
    Local $sOutBin, $sOut, $aOut, $sRead, $hDir, $sAttrib
	
	; Dim $sDirSource = 'C:\'
	; Спасибо за поправку madmasles`у 
	; http://autoit-script.ru/index.php?topic=5191.msg37866#msg37866
    If StringRight($sPath, 1) == '\' Then ;нужно, если $sPath - диск (например C:\)
		$sPath = StringTrimRight($sPath, 1)
	EndIf
	
    Switch $iFlag
        Case 1
            $sAttrib = ' /A-D'
        Case 2 
            $sAttrib = ' /AD'
        Case Else 
            $sAttrib = ' /A'
    EndSwitch
    
    $sOut = StringToBinary('0' & @CRLF, 2)
    $aMasks = StringSplit($sFileMask, ';')
    
    For $i = 1 To $aMasks[0]
        $hDir = Run(@ComSpec & ' /U /C DIR "' & $sPath & '\' & $aMasks[$i] & '" /S /B' & $sAttrib, @SystemDir, @SW_HIDE, 6)
        
        While 1
            $sRead = StdoutRead($hDir, False, True)
            
            If @error Then
                ExitLoop
            EndIf
            
            If $sRead <> "" Then
                $sOut &= $sRead
            EndIf
        Wend
    Next
    
    $aOut = StringRegExp(BinaryToString($sOut, 2), '[^\r\n]+', 3)
    
    If @error Then
        Return SetError(1)
    EndIf
    
    $aOut[0] = UBound($aOut)-1
    Return $aOut
EndFunc



Добавлено:
Сообщение автоматически объединено:

Спасибо madmasles, вы правы! Я чего-то зациклился на папке, как и просил SVD :(

P.S. Почему-то я не могу ставить плюсы пользователям :( Интересно так у всех?!
 
Автор
S

SVD

Новичок
Сообщения
9
Репутация
2
Garrett
Супер, теперь то что надо :smile: Заметил особенность - конечный каталог создается только в корне диска, тоесть нет возможности его перенести в другую директорию - по крайней мере у меня не получилось) -- но это лирика, скорее интерес чем необходимость. Огромное спасибо за помощь, сам бы я пару недель точно возился :wacko: :beer:
 

Garrett

Модератор
Локальный модератор
Сообщения
3,999
Репутация
967
SVD [?]
конечный каталог создается только в корне диска
В данном примере да.
нет возможности его перенести в другую директорию
Есть.
Код:
Dim $sDirDestin = 'E:\MyDir\TestDir' ; и т.д. любой ваш директорий
$sDirDestin = StringReplace($sDirDestin, '\', '\\')
;...
; Поменяйте строку:
$sDestination = StringRegExpReplace($aFile[$i], '(\w:\\)(.*)', '$1' & $sDirDestin & '\\$2')
; на следующие :
; $sDirDestin = StringReplace($sDirDestin, '\', '\\') ; Oops! Не сюда!
$sDestination = StringRegExpReplace($aFile[$i], '(\w:\\)(.*)', $sDirDestin & '\\$2')
;...
 
Автор
S

SVD

Новичок
Сообщения
9
Репутация
2
Garrett
Все так просто... а я как раз смотрел справку по StringRegExpReplace, $1 и $2 - в данном случае что обозначают? точнее не что, а где задается их обозначение в скрипте? ведь это переменные как я понимаю...
 

Garrett

Модератор
Локальный модератор
Сообщения
3,999
Репутация
967
SVD [?]
$1 и $2 - в данном случае что обозначают?
Найденные вхождения (которые задаются шаблоном) в искомой строке.
Их ещё называют "карманами"
[box title=AutoIt3.chm]
StringRegExpReplace
replace - The text to replace the regular expression matching text with. To insert matched group text, \0 - \9 (or $0 - $9) can be used as back-references.
[/box]


Добавлено:
Сообщение автоматически объединено:

SVD
Я немного изменил предыдущий ответ. Поправьте у себя.
 
Автор
S

SVD

Новичок
Сообщения
9
Репутация
2
Garrett
Я немного изменил предыдущий ответ. Поправьте у себя.
Файлы переносятся куда надо, но при большом их количестве скрипт начинает тупить и в консоль выводится много знаков \
 

Garrett

Модератор
Локальный модератор
Сообщения
3,999
Репутация
967
SVD [?]
Файлы переносятся куда надо, но при большом их количестве скрипт начинает тупить и в консоль выводится много знаков \
Ошибся, извиняюсь, мысли опережают события ;D Поправил.
Код:
Dim $iMinTime = 103000
Dim $iMaxTime = 113000
Dim $sDirSource = 'C:\1'
Dim $sDirDestin = 'E:\MyDir\TestDir' ; и т.д. любой ваш директорий
$sDirDestin = StringReplace($sDirDestin, '\', '\\')

$aFile = _FileSearch($sDirSource, "*.txt")

For $i = 1 To UBound($aFile) -1

    $sLine = FileReadLine($aFile[$i])
    $aTime = StringRegExp($sLine, '(\d{2}):(\d{2}):(\d{2})', 1)

    If IsArray($aTime) Then
        $nTime = Number($aTime[0] & $aTime[1] & $aTime[2])
        
        If $nTime > $iMinTime And $nTime < $iMaxTime Then
            $sDestination = StringRegExpReplace($aFile[$i], '(\w:\\)(.*)', $sDirDestin & '\\$2')
            FileCopy($aFile[$i], $sDestination, 9)
        EndIf
    EndIf
Next

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; $iFlag = 0 - Файлы и папки (по умолчанию)
; $iFlag = 1 - Только файлы
; $iFlag = 2 - Только папки
;
; Source function http://forum.oszone.net/post-1339621.html#post1339621
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Func _FileSearch($sPath, $sFileMask, $iFlag = 0)
    Local $sOutBin, $sOut, $aOut, $sRead, $hDir, $sAttrib
    
    ; Dim $sDirSource = 'C:\'
    ; Спасибо за поправку madmasles`у 
    ; http://autoit-script.ru/index.php?topic=5191.msg37866#msg37866
    If StringRight($sPath, 1) == '\' Then ;нужно, если $sPath - диск (например C:\)
        $sPath = StringTrimRight($sPath, 1)
    EndIf
    
    Switch $iFlag
        Case 1
            $sAttrib = ' /A-D'
        Case 2 
            $sAttrib = ' /AD'
        Case Else 
            $sAttrib = ' /A'
    EndSwitch
    
    $sOut = StringToBinary('0' & @CRLF, 2)
    $aMasks = StringSplit($sFileMask, ';')
    
    For $i = 1 To $aMasks[0]
        $hDir = Run(@ComSpec & ' /U /C DIR "' & $sPath & '\' & $aMasks[$i] & '" /S /B' & $sAttrib, @SystemDir, @SW_HIDE, 6)
        
        While 1
            $sRead = StdoutRead($hDir, False, True)
            
            If @error Then
                ExitLoop
            EndIf
            
            If $sRead <> "" Then
                $sOut &= $sRead
            EndIf
        Wend
    Next
    
    $aOut = StringRegExp(BinaryToString($sOut, 2), '[^\r\n]+', 3)
    
    If @error Then
        Return SetError(1)
    EndIf
    
    $aOut[0] = UBound($aOut)-1
    Return $aOut
EndFunc
 
Автор
S

SVD

Новичок
Сообщения
9
Репутация
2
Garrett
эхх как вам наверно скучно возится с такими лошарами как я - одну строчку, и то куда надо вставить, не догадался ;D Спасибо, теперь все идеально :smile:
 

Garrett

Модератор
Локальный модератор
Сообщения
3,999
Репутация
967
Верх