Что нового

Изменение определенных значений внутри cfg файлов

prokazzza

Новичок
Сообщения
160
Репутация
2
Версия AutoIt: 3.3.6.1

Описание: Существует каталог с несколькими подкаталогами. В каждом из подкаталогов есть файлы конфигураций (cfg) с одинаковыми названиями (при этом имена подкаталогов разные). В этих файлах необходимо найти и изменить определенные параметры.

К примеру среди кучи строк в этом файле найти строку:
Код:
st Upadter_mode "20x24"
И заменить его другими значениями:
Код:
st Upadter_mode "10x14"
Примечания: Необходимость в скрипте возникла из-за повседневного вбивания параметров вручную. Желательно чтобы отсутствовал ярлык скрипта в трее.

Заранее благодарю за помощь!
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
qsort
Предупреждение здесь исключительно посты максимально приближенные к решению, или самое решение - готовое
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
prokazzza
Вроде файлы .cfg имеют структуру ини-файла. Вы приведите образец файла .cfg и скажите, какие параметры могут быть изменены.
 
Автор
P

prokazzza

Новичок
Сообщения
160
Репутация
2
madmasles сказал(а):
prokazzza
Вроде файлы .cfg имеют структуру ини-файла. Вы приведите образец файла .cfg и скажите, какие параметры могут быть изменены.

Не совсем. Файлы слишком большие по содержанию, могу только сказать что они имеют простой вид:

Значение1 "параметр"
Значение2 "параметр"
Значение3 "параметр"

И т.д.
Могу только добавить что значения которые нужно поменять находятся в 1348 строке. Саму строку и как её нужно поменять я описывал выше:

К примеру среди кучи строк в этом файле найти строку:

Код:
st Upadter_mode "20x24"

И заменить его другими значениями:

Код:
st Upadter_mode "10x14"
 

dronet

Знающий
Сообщения
46
Репутация
8
Будет зделанно - немного подожди... :smile:
 

dronet

Знающий
Сообщения
46
Репутация
8
Попробуй это, на мой взгляд самый лёхгкий и простой. Для новичьков есть описания и
Режим отрабатывания в виде "ConsoleWrite" < их можно затем удалить.
Код:
#Cs  Проверенно на такой структуре...====================================================
1
2
3"Заменяемый текст!"
4
5
6
7
 45654645 45654654654654 45654654654654  Заменяемый текст! 5654654654645654 65454



               Заменяемый текст!
#Ce =====================================================================================

#Include <File.au3>
#Include <Array.au3>
Opt('TrayIconHide', 1)
Opt('MustDeclareVars', 1)
;~ ***
Global $i = 0, $j = 0, $sStr
Global $TIMER_In = TimerInit() ;~> ПРОВЕРКА! Засечь время...   ~ Round(TimerDiff($TIMER_In)/1000, 1)
Global $sExt = 'txt'; <~ Сменить на расширение которое нужно.
Global $aReturn = _FileSearch('G:\ВИДЕО', "*."&$sExt) ; <~ Сменить на директорию в которой искать, берёт подкатегории тоже.
Global $sNewText = 'Новый текст'
Global $sText = 'Заменяемый текст!'
Global $Flag = 1
; Flag =
         ; 0 = не зависит от регистра написания согласно языку пользователя (по умолчанию)
         ; 1 = зависит от регистра написания
         ; 2 = не зависит от регистра написания согласно базовому/наиболее быстрому сравнению
;~ ***
ConsoleWrite('Найдено: '& $aReturn[0] &' Файлов за: ' & Round(TimerDiff($TIMER_In)/1000, 1) & @CRLF) ; Для проверки, а так не нужно
;~ ***
Dim $aTest[1]
For $i1 = 1 To $aReturn[0]
Local $Fl = FileOpen($aReturn[$i1]&'.'&$sExt, 0)
ConsoleWrite($aReturn[$i1] & @CRLF) ; Для проверки, а так не нужно
_Find($aReturn[$i1])
FileClose($Fl)
Next
;~ ***
If Not $j Then
    MsgBox(0, '', 'Нет совпадений.')
Else
	MsgBox(0, '', 'Найдено совпадений: ' & $j & ' в строках:     '& @CRLF & 'Время: ' & Round(TimerDiff($TIMER_In)/1000, 1))
EndIf

;~ ***
Func _Find($hFile)
While 1
    $i += 1
    Local $sTemp = FileReadLine($hFile, $i)
    If @error = -1 Then ExitLoop
    If StringInStr($sTemp, $sText, $Flag) Then
ConsoleWrite('Найденно в файле: '& $hFile & @CRLF & 'Строка: ' & $i & @CRLF & 'Содержание: ' & $sTemp & @CRLF) ; Для проверки, а так не нужно
		$sStr = StringRegExpReplace($sTemp, $sText, $sNewText)
ConsoleWrite($sStr & @CRLF) ; Для проверки, а так не нужно
		_FileWriteToLine($hFile, $i, $sStr, 1)
		If @error Then ExitLoop
        $j += 1
        ReDim $aTest[$j + 1]
        $aTest[$j] = $i
    EndIf
WEnd
EndFunc
;~ ***
;$iFlag = 0 - Файлы и папки (по умолчанию)
;$iFlag = 1 - Только файлы
;$iFlag = 2 - Только папки
Func _FileSearch($sPath, $sFileMask, $iFlag = 1)
    Local $sOutBin, $sOut, $aOut, $sRead, $hDir, $sAttrib, $aMasks
    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





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

Ссори ошибочька вышла... :shok:
Нужно заменить код:
Код:
;~ ***
Dim $aTest[1]
For $i1 = 1 To $aReturn[0]
Local $Fl = FileOpen($aReturn[$i1]&'.'&$sExt, 0)
ConsoleWrite($aReturn[$i1] & @CRLF) ; Для проверки, а так не нужно
_Find($aReturn[$i1])
FileClose($Fl)
Next
;~ ***


На код:
Код:
;~ ***
Dim $aTest[1]
For $i1 = 1 To $aReturn[0]
Local $Fl = FileOpen($aReturn[$i1]&'.'&$sExt, 0)
ConsoleWrite($aReturn[$i1] & @CRLF) ; Для проверки, а так не нужно
Global $i = 0
_Find($aReturn[$i1])
FileClose($Fl)
Next
;~ ***


Тогда работает правильно
 
Автор
P

prokazzza

Новичок
Сообщения
160
Репутация
2
dronet

Спасибо работает отлично, ты просто гений! А можно немного доработать скрипт?

Можно безопасно закоментировать (не удалить) строки относящиеся к отображению консольных окон типо Найдено 1 совпадение и т.п.

И можно ли выставить в поиске нескольких значений, то есть ищем значения не одно, а из списка возможных, к примеру ищем возможные варианты - Тип1, Тип2, Тип3 и т.д. и заменяем их одним значением - Тип4.

МОжно ли клонировать раздал скрипта и сделать так чтобы он искал не только одно значение а несколько других сразу, тоесть (с учетом предыдущего Тип1, Тип2...):

Global $sNewText = 'Новый текст'
Global $sText = 'Заменяемый текст1, Заменяемый текст2, Заменяемый текст3, Заменяемый текст4, '

И ниже ищем другое значение

Global $sNewText = 'Еще один Новый текст'
Global $sText = 'Текст1, Текст2, Текст3, Текст4, '
 

dronet

Знающий
Сообщения
46
Репутация
8
Можно всё можно
Только надо немного поколдовать
если получитса пример будет позже
 

dronet

Знающий
Сообщения
46
Репутация
8
Вот зделал, да и самому тоже пригодитса.
NB! Делайте предварительные резервные копии фаилов.
Код:
#Cs  Проверенно на такой структуре...====================================================
     на трёх файлах в разных директориях - по назначению...
1
2
3"Заменяемый текст 1"
4
5Заменяемый текст 3
6
7
 45654645 45654654654654 45654654654654  Заменяемый текст 2 5654654654645654 65454

(Заменяемый текст 4)(Заменяемый текст 1)(Заменяемый текст 3)(Заменяемый текст 2)'

               Заменяемый текст 3

#Ce =====================================================================================
; http://autoit-script.ru/index.php?topic=3852.msg28088;topicseen#new
#Include <File.au3>
#Include <Array.au3>
Opt('MustDeclareVars', 1) ; Так для отладки, чтоб переменные были объявленны.
Opt('TrayIconHide', 1) ; Скыть иконку в трее, 0=Показать.
;==========================================================================================================================================
Global $i = 0, $j = 0
Global $TIMER_In = TimerInit() ;~> Засечь время...
Global $sExt = 'txt'; <~ Сменить на расширение которое нужно.
Global $aReturn = _FileSearch('G:\ВИДЕО', "*."&$sExt) ; <~ Сменить на директорию в которой искать, берёт подкатегории тоже.
Global $sNewText = 'Новый текст'
Dim $sText = StringSplit("Заменяемый текст 1|Заменяемый текст 2|Заменяемый текст 3|Заменяемый текст 4", "|", 2) ; < 2'ка меняет заменяемый текст целиком.
; Текст для замены,
         ; начало == ("Заменяемый текст 1|
         ; последовательность идёт между  == |
         ; заканчиваетса == |Заменяемый текст 4",
		 ; '|' == Символ деляший заменяемые значения.

Global $Flag = 1
; Flag = Замена производитса...
         ; 0 = не зависит от регистра написания согласно языку пользователя (по умолчанию)
         ; 1 = зависит от регистра написания
         ; 2 = не зависит от регистра написания согласно базовому/наиболее быстрому сравнению

;==========================================================================================================================================
;~ ConsoleWrite('Найдено: '&$aReturn[0]&' Файлов. За: '&Round(TimerDiff($TIMER_In)/1000, 1)&' мсек'&@CR)

Dim $aTest[1]
For $i1 = 1 To $aReturn[0]
Local $Fl = FileOpen($aReturn[$i1]&'.'&$sExt, 0)
;~ ConsoleWrite($aReturn[$i1] & @CR)
Global $i = 0
_Find_Text_And_Replace($aReturn[$i1])
FileClose($Fl)
Next

;==========================================================================================================================================
;If Not $j Then
;    MsgBox(0, '', 'Нет совпадений.')
;Else
;    MsgBox(0, '', 'Найдено совпадений: '&$j&' (в строках)     '&@CR&'Время на замену ушло: '&Round(TimerDiff($TIMER_In)/1000, 1)&' мсек')
;EndIf

; END ==>


;==========================================================================================================================================
; FUNCIONS
Func _Find_Text_And_Replace($hFile) ; Поиск и замена...
While 1
    $i += 1
    Local $sTemp = FileReadLine($hFile, $i)
    If @error = -1 Then ExitLoop
	For $s In $sText
		If StringInStr($sTemp, $s, $Flag) Then
								;~ConsoleWrite('---------------------------------------------' & @CR)
								;~ConsoleWrite('Фаил: ' &$hFile &@CR)
								;~ConsoleWrite('Заменяемая строка: ' &$i &@CR)
								;~ConsoleWrite('Заменяемое содержание: ' &$sTemp &@CR)
			$sTemp = StringRegExpReplace($sTemp, $s, $sNewText)
			_FileWriteToLine($hFile, $i, $sTemp, 1)
			If @error Then ExitLoop
				$j += 1
				ReDim $aTest[$j + 1]
				$aTest[$j] = $i
								;~ConsoleWrite('На содержание: '  &$sTemp &@CR)
								;~ConsoleWrite('---------------------------------------------' & @CR)
		EndIf
	Next
WEnd
EndFunc   ;==>_Find_Text_And_Replace

;==========================================================================================================================================
; $iFlag = 0 - Файлы и папки (по умолчанию)
; $iFlag = 1 - Только файлы
; $iFlag = 2 - Только папки
; Автор данного кода мне к сожелению не известен, код нашол у себя на складе :)
Func _FileSearch($sPath, $sFileMask, $iFlag = 1) ; Поиск файлов...
    Local $sOutBin, $sOut, $aOut, $sRead, $hDir, $sAttrib, $aMasks
    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   ;==>_FileSearch

Ну и вариант с множеством параметрав для замены, специально для автора темы :smile:
Код:
#Cs  Проверенно на такой структуре...====================================================
     на трёх файлах в разных директориях - по назначению... с тремя параметрами
1
2
3"Заменяемый текст 5"
4                      Заменяемый текст g
5Заменяемый текст 7
6
7
 45654645 45654654654654 45654654654654  Заменяемый текст 6 5654654654645654 65454

(Заменяемый текст 8)(Заменяемый текст 5)(Заменяемый текст 7)(Заменяемый текст 6)'

               Заменяемый текст 7  Заменяемый текст .

1
2  Заменяемый текст 9|Заменяемый текст v|
3"Заменяемый текст 1"
4
5Заменяемый текст 3
6
7
 45654645 45654654654654 45654654654654  Заменяемый текст 2 5654654654645654 65454

(Заменяемый текст 4)(Заменяемый текст 1)(Заменяемый текст 3)(Заменяемый текст 2)'

               Заменяемый текст 3  Заменяемый текст v

#Ce =====================================================================================
; http://autoit-script.ru/index.php?topic=3852.msg28088;topicseen#new
#Include <File.au3>
#Include <Array.au3>
Opt('MustDeclareVars', 1) ; Так для отладки, чтоб переменные были объявленны.
Opt('TrayIconHide', 1) ; Скрыть иконку в трее, 0=Показать.
;==========================================================================================================================================
Global $i = 0, $j = 0
Dim $aTest[1]
Global $TIMER_In = TimerInit() ;~> Засечь время...
Global $sExt = 'txt'; <~ Сменить на расширение которое нужно.
Global $aReturn = _FileSearch('G:\ВИДЕО', "*."&$sExt) ; <~ Сменить на директорию в которой искать, берёт подкатегории тоже.
Dim $sNewText[3] = [2, 'Новый текст-1', 'Новый текст 2']
Dim $sText1 = StringSplit("Заменяемый текст 1|Заменяемый текст 2|Заменяемый текст 3|Заменяемый текст 4", "|", 2) ; < 2'ка меняет заменяемый текст целиком.
Dim $sText2 = StringSplit("Заменяемый текст 5|Заменяемый текст 6|Заменяемый текст 7|Заменяемый текст 8", "|", 2)
; Текст для замены,
         ; начало == ("Заменяемый текст 1|
         ; последовательность идёт между  == |
         ; заканчиваетса == |Заменяемый текст 4",
		 ; '|' == Символ деляший заменяемые значения.

Global $Flag = 1
; Flag = Замена производитса...
         ; 0 = не зависит от регистра написания согласно языку пользователя (по умолчанию)
         ; 1 = зависит от регистра написания
         ; 2 = не зависит от регистра написания согласно базовому/наиболее быстрому сравнению

#Cs
На заметку...      [3 замены значит = $sNewText[4]... [2 замены значит = $sNewText[3]...
Dim $sNewText[4] = [3, 'Новый текст 1', 'Новый текст 2', 'Новый текст 3'] ; Если для трёх замен! = + 1 новый текст = + 1 новые замены [ Dim $sText+НОМЕР ]
Dim $sText3 = StringSplit("Заменяемый текст 9|Заменяемый текст .|Заменяемый текст v|Заменяемый текст g", "|", 2) ; Новые замены 3.
#Ce
;==========================================================================================================================================
;~ ConsoleWrite('Найдено: '&$aReturn[0]&' Файлов. За: '&Round(TimerDiff($TIMER_In)/1000, 1)&' мсек'&@CR)

For $i1 = 1 To $aReturn[0]
	Local $Fl = FileOpen($aReturn[$i1] & '.' & $sExt, 0)
	For $NR = 1 To $sNewText[0]
		Local $sText = Eval('sText' & $NR)
;~ 		ConsoleWrite($aReturn[$i1] & @CR)
		Global $i = 0
		_Find_Text_And_Replace($aReturn[$i1])
		FileClose($Fl)
	Next
Next
;==========================================================================================================================================
;If Not $j Then
;    MsgBox(0, '', 'Нет совпадений.')
;Else
;    MsgBox(0, '', 'Найдено совпадений: '&$j&' (в строках)     '&@CR&'Время на замену ушло: '&Round(TimerDiff($TIMER_In)/1000, 1)&' мсек')
;EndIf

; END ==>


;==========================================================================================================================================
; FUNCIONS
Func _Find_Text_And_Replace($hFile) ; Поиск и замена...
	While 1
		$i += 1
		Local $sTemp = FileReadLine($hFile, $i)
		If @error = -1 Then ExitLoop
		For $s In $sText
			If StringInStr($sTemp, $s, $Flag) Then
;~								ConsoleWrite('---------------------------------------------' & @CR)
;~								ConsoleWrite('Фаил: ' &$hFile &@CR)
;~								ConsoleWrite('Заменяемая строка: ' &$i &@CR)
;~								ConsoleWrite('Заменяемое содержание: ' &$sTemp &@CR)
				$sTemp = StringRegExpReplace($sTemp, $s, $sNewText[$NR])
				_FileWriteToLine($hFile, $i, $sTemp, 1)
				If @error Then ExitLoop
				$j += 1
				ReDim $aTest[$j + 1]
				$aTest[$j] = $i
;~								ConsoleWrite('На содержание: '  &$sTemp &@CR)
;~								ConsoleWrite('---------------------------------------------' & @CR)
			EndIf
		Next
	WEnd
EndFunc   ;==>_Find_Text_And_Replace

;==========================================================================================================================================
; $iFlag = 0 - Файлы и папки (по умолчанию)
; $iFlag = 1 - Только файлы
; $iFlag = 2 - Только папки
; Автор данного кода мне к сожелению не известен, код нашол у себя на складе :)
Func _FileSearch($sPath, $sFileMask, $iFlag = 1) ; Поиск файлов...
    Local $sOutBin, $sOut, $aOut, $sRead, $hDir, $sAttrib, $aMasks
    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   ;==>_FileSearch


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

qsort сказал(а):
[quote author=prokazzza]
В принципе, нечто похожее когда-то было, чуть-чуть изменив, может быть примерно так:
Код:
$Array_files[1] = "" ; Имя первого файла (указываем полный путь)
$Array_files[2] = ""
FileOpen($dir & "tmp.tmp" , 2)

А если у меня фаилов то много? да и если я вообше не знаю их названия... :smile:
флаг - 2 = открыть для записи и удалить имеющееся содержание совсем :shok:

Мне так кажетса "этот скрипт вообше для выдёргивания текста из $Array_files[n]
И запись в один фаил" == а так я не проверял.
 

gregaz

AutoIT Гуру
Сообщения
1,166
Репутация
299
Может сделать все проще :

Создаю тестовый файл 1.cfg :
Код:
$hFile=FileOpen (@ScriptDir & "\1.cfg",1)
If $hFile = -1 Then
    MsgBox(0, "Error", "Unable to open file.")
    Exit
EndIf
For $i=1 To 30
   $iRandom=Random(1,9,1)
   $sLine='st Upadter_mode "' & $iRandom & "0x" & $iRandom & '4"'
   FileWriteLine($hFile, $sLine & @CRLF)
Next
FileClose($hFile)


Ну и сам скриптик :
Код:
#NoTrayIcon
$sFile=@ScriptDir & "\1.cfg"

$sFind="10x14,20x24,30x34,40x44"
$sReplace="aaaaa0xa4"
$sNewText=Replace($sFile,$sFind,$sReplace)

MsgBox(0,'File NewText',FileRead($sFile))


Func Replace($sFile,$sFind,$sReplace)
   $sText=FileRead($sFile)
   $sFind=StringReplace($sFind,",","|")
   $sPattern = '(?si)(.+?")(?:' & $sFind & ')(".+?)'
   $sRezult = StringRegExpReplace ( $sText ,$sPattern,'${1}' & $sReplace & '${2}')
   $iMsg= MsgBox(4,"Инфо","В файле : " & $sFile & @CRLF & " Найдено строк : " & $sFind & @CRLF & "В количестве : " & @extended/2 & @CRLF & "Изменить файл ?")
   If  $iMsg =7 Then Return 
  FileCopy($sFile,@ScriptDir & "\1.bak"); На всякий случай -резервная копия 
$hFile=FileOpen ($sFile,2)
   FileWrite($hFile,$sRezult)
   FileClose($hFile)
   Return $sRezult
EndFunc
 

gregaz

AutoIT Гуру
Сообщения
1,166
Репутация
299
prokazzza [?]
Выдает ошибку в 42 строке:

Обрати внимание на кавычки (перед первым фрагментом)

У тебя в заменяемом фрагменте уже есть " , значит в операторе надо заменить двойные кавычки на одинарные
Примерно так :
Код:
Dim $sText1 = StringSplit('st Upadter_mode "20x24"|Заменяемый текст 2|Заменяемый текст 3|st Upadter_mode "40x24"'        ............
 
Автор
P

prokazzza

Новичок
Сообщения
160
Репутация
2
dronet gregaz Спасибо большое все прекрасно работает!!! :beer:
 

dronet

Знающий
Сообщения
46
Репутация
8
gregaz
Можно, конешно попробовать.
Твой способ замены текста, как время будет я попробую прикрутить в скрипт.
 

dronet

Знающий
Сообщения
46
Репутация
8
Вот. Переделал алгоритм досконально, теперь намного лучьше. Из за универсальности можно использовать во многих целях.

Код:
#Region / Описание.
;§§[ INDEX ]§§ ============================================================================================================================
; Имя название ...............: Поиск и замена текста в файлах.
; Версия .....................: 1.2.0.0 ~> 1. Февраль. 2011.
; Последняя модификация ......: 01.02.2011
; Требования .................: AutoIt v3.3.6.0+, испытано на работоспособность, на WindowsXP SP3 RUS.
; Язык .......................: Русский
; Описание ...................: Пойск и замена текста в файлах.
;		                      [ Возможность указать более одного фильтра (маска) для файлов.
;		                      [ Возможность указать более одного параметра замены.
;		                      [ Возможность указать более одного фильтра замены текста.
;		                      [ Хорошая скорость поиска файлов, и замены текста - если фильтры (маски) указанны в разумных пределах. :)
;		                      [ Есть параметр - зависит/не зависит, от регистра написания.
;		                      [ Есть возможность постоянной зоздания резервной копии, не перезаписывая прошлую резервную копию.
; Включённые библиотеки ......: ~ ~ ~ ~
; Примечания .................: Опсуждение 'http://autoit-script.ru/index.php?topic=3852.msg28088;topicseen#new'
; Автор ......................: Andress. P.   <[§ DRON §]>
; Включенные функции .........:
;		                      [ _Files_Search Предложенный код от 'Creat0R' на форуме 'http://forum.oszone.net/post-1324937.html'
;		                      [ _Find_And_Replace_Text
;		                      [ _Vrite_To_File
; Недокументированые функции .: Отсутствуют.
; История версии .............:
;		                      [ 1.2.0.0 ~> Созданна первая версия, на данный момент 'Beta'

; Пример испытуемого файла ...:
#Cs Проверенно на данной структуре - на трёх файлах в разных директориях - по назначению '$hDirectory' с тремя фильтрами замены.
2 1 2
3"Заменяемый текст 5"
4                      Заменяемый текст б 76
5Заменяемый текст 7
 45654645 45654654654654 45654654654654  Заменяемый текст 6 5654654654645654 65454
(Заменяемый текст 8)(Заменяемый текст 5)(Заменяемый текст 7)(Заменяемый текст 6)'
               Заменяемый текст 7  Заменяемый текст А
1
2  Заменяемый текст 9|Заменяемый текст в|
3"Заменяемый текст 1"
4
5Заменяемый текст 3  6 7 7
 45654645 45654654654654 45654654654654  Заменяемый текст 2 5654654654645654 65454
(Заменяемый текст 4)(Заменяемый текст 1)(Заменяемый текст 3)(Заменяемый текст 2)'
               Заменяемый текст 3  Заменяемый текст в
#Ce
;==========================================================================================================================================
#EndRegion
Opt('MustDeclareVars', 1)
#Region / Настройки пользователя.
;==========================================================================================================================================
; Настройка отображения иконки в трее.
Opt('TrayIconHide', 1)
	 ; 0 = Показать иконку в трее.
	 ; 1 = Скрыть иконку в трее.

;==========================================================================================================================================
; Фильтр искомого/искомых файла/ов.
Global $sMasks = '*.cfg'
;~ Global $sMasks = '*.txt;*.ppk'
	 ; Например...
	 ; [ 'Tekst1.txt;Tekst2.txt;Tekst3.txt' ]
	 ; [ '*.txt;*.ini' ]
	 ; [ '*.txt' ]
	 ; [ '*.*' ]

;==========================================================================================================================================
; Директория в которой искать.
Global $hDirectory = @DesktopDir&'\000'
	 ; Например...
	 ; [ 'C:\Windows' ]
	 ; [ 'C:\Documents and Settings\Desktop' ]

;==========================================================================================================================================
; Новые тексты.
Global $sNewTexts = 'Новый текст 1;Новый текст 2;Новый текст 3'
	 ; Например...
	 ; [ 'Новый текст 1' ] Для одной замены.
	 ; [ 'Новый текст 1;Новый текст 2' ] Для Двух замен.
	 ; Для каждого 'Новыго текста' должна быть ячейка с текстом для замены, под соотведствуюшим номером.

;==========================================================================================================================================
; Тексты, которые нужно заменить новыми текстами.
Global $sOldTexts1 = 'Заменяемый текст 1;Заменяемый текст 2;Заменяемый текст 3;Заменяемый текст 4'  ;> на - новый текст 1
Global $sOldTexts2 = 'Заменяемый текст 5;Заменяемый текст 6;Заменяемый текст 7;Заменяемый текст 8'  ;> на - новый текст 2
Global $sOldTexts3 = 'Заменяемый текст 9;Заменяемый текст А;Заменяемый текст б;Заменяемый текст в'  ;> на - новый текст 3
	 ; Для одной замены  ячейка с текстами или одним текстом под номером [ 1 ]
	 ; Для Двух замен, две ячеики с номерами [ 1 ] и [ 2 ] И,Т,Д.

;==========================================================================================================================================
; Режим замены. Рекомендованно значение '1'
Global $Flag = 1
	 ; Flag = Замена производитса...
	 ; 0 = не зависит от регистра написания согласно языку пользователя (по умолчанию).
	 ; 1 = зависит от регистра написания.
	 ; 2 = не зависит от регистра написания согласно базовому/наиболее быстрому сравнению.

;==========================================================================================================================================
; Настройка резервной копии. Рекомендованно значение '1'
Global $iBack = 1
	 ; 0 = Не делать резервную копию.
	 ; 1 = Делать резервную копию.

#EndRegion
#Region / Основные параметры.
;==========================================================================================================================================
Global $TIMER_TOTAL = TimerInit()  ; Таймер 'старт'...
Global $iTIMER_SEARCH, $aFile[1]
Global $aTotalFiles = 0
Global $iTotalRepl = 0
; ..............................
#EndRegion

_Find_And_Replace_Text($hDirectory, $sMasks, $sNewTexts, $Flag, $iBack)

;~ ConsoleWrite('Файлов найденно: '&$aFile[0]&' За: '&$iTIMER_SEARCH&' Мсек'&@CR)
;~ ConsoleWrite('Замен произведенно: '&$iTotalRepl&' В файлах: '&$aTotalFiles&' За: '&Round(TimerDiff($TIMER_TOTAL)/1000, 1)&' Мсек'&@CR)


#Region / Функции.
;==========================================================================================================================================
; Функция _Find_And_Replace_Text
Func _Find_And_Replace_Text($hDirectory, $sMasks, $sNewTexts, $Fl, $iBack)
	Local $aFile = _Files_Search($hDirectory, $sMasks)
	If $aFile = False Then Exit
	For $i1 = 1 To $aFile[0]
		Local $TIMER_REPL = TimerInit(), $iExt = 0, $sFileText
		Local $sFileText = FileRead($aFile[$i1])
		If $sFileText = -1 Then Return SetError(1, 2, 0) ; Фаил не удалось открыть.
		If Not $sFileText = ''  Then
			Local $sNewText = StringSplit($sNewTexts, ';')
			For $i2 = 1 To $sNewText[0]
				Local $sOldTexts = StringSplit(Eval('sOldTexts' & $i2), ';', 2)
				For $sOldText In $sOldTexts
					If $sOldText = '' Then Return SetError(2, 2, 0) ; Не обозначен заменяемый текст.
					If StringInStr($sFileText, $sOldText, $Fl) Then
						$sFileText = StringReplace($sFileText, $sOldText, $sNewText[$i2])
						$iExt += @extended
						$iTotalRepl += @extended
					EndIf
				Next
			Next
		EndIf
		If $iExt > 0 Then
		Local $aResult = _Vrite_To_File($aFile[$i1], $sFileText, $iBack)
		If $aResult = 0 Then Return SetError(3, 2, 0) ; Небыла произведена запись
		$aTotalFiles += $aResult
;~ 		ConsoleWrite( _
;~ 		'===================================================================================='&@CR& _
;~ 		'Фаил: '&$aFile[$i1]&@CR& _
;~ 		'Замен произведенно: '&$iExt&' За: '&Round(TimerDiff($TIMER_REPL)/1000, 1)&' Мсек'&@CR& _
;~ 		'===================================================================================='&@CR)
		EndIf
	Next
Return $iTotalRepl
EndFunc   ;==>_Find_And_Replace_Text

;==========================================================================================================================================
; Функция _Vrite_To_File ; Запись в файл обработанных данных...
Func _Vrite_To_File($sFile, $sData, $iBack = 1, $iF = 1)
	If ($sFile = '' Or $sData = '') Then Return SetError(1, 3, 0) ; Указанны неверние параметры.
;~ 	If Not FileExists($sFile)
	If StringInStr(FileGetAttrib($sFile), "R") Then Return SetError(2, 3, 0)
	If  $iBack = 1 Then
		While FileExists($sFile &'.bak_' &$iF) ; Если резервный файл уже сушествует.
		$iF +=  1
		WEnd
		FileCopy($sFile, $sFile &'.bak_' &$iF, 0)
	EndIf
	Local $hFile=FileOpen($sFile,2)
	If $hFile = -1 Then Return SetError(3, 3, 0) ; Фаил не удалось открыть.
	Local $hWriteFile = FileWrite($hFile,$sData)
	FileClose($hFile)
	If $hWriteFile = -1 Then Return SetError(4, 3, 0 ) ; Фаил не удалось создать.
	Return 1
EndFunc

;==========================================================================================================================================
; Функция _Files_Search ; Поиск файлов...
Func _Files_Search($sPath, $sFileMask)
    Local $hDir, $sRead, $aOut, $TIMER_SEARCH = TimerInit()
	Local $sPIF = StringInStr(FileGetAttrib($sPath & "\"), "D")
	If Not $sPIF Then Return SetError(MsgBox(0, 'Ошибка!', 'Не верно указанна директория.'), '', 0)
    Local $sOut = StringToBinary('0' & @CRLF, 2)
    Local $aMasks = StringSplit($sFileMask, ';')
    For $i = 1 To $aMasks[0]
		If $aMasks[$i] = ''  Then Return SetError(MsgBox(0, 'Ошибка!', 'Не верно обозначенна маска файлов.'), '', 0)
        $hDir = Run(@ComSpec &' /U /C DIR "'& $sPath &'\'& $aMasks[$i] &'" /S/B/A-D', @SystemDir, @SW_HIDE, 6)
        While 1
            $sRead = StdoutRead($hDir, False, True)
            If @error Then ExitLoop
            If $sRead <> "" Then
                $sOut &= $sRead
            EndIf
        Wend
    Next
    $aOut = StringRegExp(BinaryToString($sOut, 2), '[^\r\n]+', 3)
	If @error Then Return SetError(3, 1, 0)
    $aOut[0] = UBound($aOut)-1
	$iTIMER_SEARCH = Round(TimerDiff($TIMER_SEARCH)/1000, 1)
    Return $aOut
EndFunc   ;==>_Files_Search

#EndRegion
;
 
Автор
P

prokazzza

Новичок
Сообщения
160
Репутация
2
Новый скрипт при запуске выдает ошибку, скрин:



Есть еще 2 штуки если можно добавь плиз их в скрипт

1 это тута http://autoit-script.ru/index.php?topic=3896.0 с прошлым скриптом она не совместима выдает какую то ошибку, желательно чтоб можно было указать несколько файлов для удаления.

и второе запуск определенного приложения после всех выполненных функций.

ну и чтоб консольных окошек не было )))
 

dronet

Знающий
Сообщения
46
Репутация
8
Ну начнём стого что эта ошибка в следствии того что Массив не содержит хотябы одного Каталога
Методы записи директории:
Global $hDirectory = 'C:\Windows'
Global $hDirectory = 'C:\Documents and Settings\Desktop'
В конце адресса НЕ ставитса Слэш \

Записи в таком роде @DesktopDir&'\000'
Нужно правильно записывать - в этом поможет справка

и еше правильно оформить фильтр
$sMasks = 'Tekst1.txt;Tekst2.txt;Tekst3.txt' < название и расширение
$sMasks = '*.txt;*.ini' < так можно два типа указать
$sMasks = '*.cfg' < Только файлы с рашширением cfg
$sMasks = '*.*' < Под сканирование попадут все файлы с расширением, замедлит процесс
$sMasks = 'Tekst1.*' только название расширение любое
'*' так должны попасть фаилы не имеюшие расширения

И вообше лучше если я взгяну на то как настроен ваш скрипт тогта точьно могу сказать



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

Также обновил скрипт - закоментировал 'консольные окошки'
Не понел
с прошлым скриптом она не совместима выдает какую то ошибку
Что ты хочеш зделать ??
и
и второе запуск определенного приложения после всех выполненных функций
Это можно но это уже другая тема - а то злые модэроторы будут ругать :whistle:
 
Сообщения
80
Репутация
-1
Может кто напишет как этим пользоваться уж очень он длинный, а инструкции нет. Это копировать в мой скрипт или отдельно както подкладывать, и какие команды писать?


у меня есть файл формата
Код:
значение = 1
знак равенства отделён пробелом и нет секций поэтому IniWrite работать не может, чему равно значение тоже неизвестно.
 

Medic84

Омега
Команда форума
Администратор
Сообщения
1,590
Репутация
341
dronet
То есть про другую тему ты сказал, а сам правила нарушаешь? )

Предупреждение За нарушение правил форума (пункт В.11):
Любые отрывки AutoIt кода необходимо заключать в тег [autoit]
autoit.gif
(подробнее), а обычный код соответственно в тег [code]
code.gif
(подробнее). Также большие выдержки текста помещайте под тег [spoiler]
spoiler.gif
(подробнее), там где это поддерживается естественно. Как в случае с названием темы, также короткое и эргономичное сообщение привлекает больше внимания, и шансы на получение конкретного ответа увеличиваются.


С уважением, ваш Администратор.





А еще, если плохо знаете русский язык хотя бы проверяйте Вашу орфографию здесь: Я.Спеллер, чтобы исправить элементарные ошибки.
 
Верх