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

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

Pozia 08-04-2009 07:45 1087528

Скрипт для удаления нужных слов в ini файле
 
Подскажите скрипт который удалит нужные мне заведомо известные слова из ini файла и больше ничего в нем не тронет.

proxy 08-04-2009 08:32 1087552

Если ini файл стандартный, то:
Код:

IniDelete ( "filename", "section", "key" )
Стандартный ini файл имеет вид:
[НазваниеРаздела]
Ключ=Значение

Если, что то другое, то приведите пример структуры вашего файла.

Pozia 08-04-2009 08:56 1087566

proxy, мне нужно отредактировать файл oeminfo.ini, в нем находится информация об обнавлениях винды. Вот не все слова мне там нужны. Файл выложить могу только вечером. Но суть такая что нужно чтобы скрипт нашел в этом файле заранее прописанные мною слова и удалил их. Если слов нет или файла не нашел то ничего пусть не делает и завершит свою работу

proxy 08-04-2009 09:12 1087569

Код:

#include <File.au3>
_ReplaceStringInFile($szFileName, $szSearchString, $szReplaceString, $fCaseness = 0, $fOccurance = 1)

ооооо....да он имееет обычную структуру, IniDelete очень подойдет.

Pozia 08-04-2009 09:22 1087575

proxy, поясните как пользоваться вашей командой. Если неизвестна в какой строке находится слово все равно найдет и удалит?

proxy 08-04-2009 09:59 1087603

Цитата:

Цитата Pozia
Если неизвестна в какой строке находится слово все равно найдет и удалит? »

вернее - всеравно найдет и заменит.
К примеру можно заменять на пустую строку = ''

Русская справка AutoIt > Указатель библиотечных функций > Файлы > _ReplaceStringInFile
или
Справка по UDF > File Management > _ReplaceStringInFile
(эта справка "идет" в комплекте с компилятором, находится в корне папки установки AutoIt)

Цитата:

#Include <File.au3>
_ReplaceStringInFile($szFileName, $szSearchString, $szReplaceString[, $fCaseness = 0[, $fOccurance = 1]])

$szFileName - полный адрес файла
$szSearchString - искомая строка
$szReplaceString - заменяющая строка
$fCaseness 0 = не чувствительно к регистру (по умолчанию), 1 = чувствительно к регистру
$fOccurance 0 = заменять только первое найденное совпадение, 1 = заменять все найденные совпадение (по умолчанию)

и т.д. по справке......

Но для файла oeminfo.ini очень подойдет IniDelete, так как она представляет собой обычный ini файл.
Русская справка AutoIt > Указатель функций > Файловая система > Управление файлами инициализации > IniDelete
или
на английском

amel27 08-04-2009 11:20 1087713

вариант через RegExp, строка не должна быть первой или последней:
Код:

$sFile = "c:\Work.AU3\oem\oeminfo.ini"
$sLine = 'Line1="Телефоны службы технической поддержки:"'

$sText = StringRegExpReplace(FileRead($sFile),"(?i)\n\Q"& $sLine &"\E\r","")
FileDelete($sFile)
FileWrite($sFile, $sText)


proxy 08-04-2009 11:53 1087739

Цитата:

строка не должна быть первой или последней:
тогда уж так:

Код:

$sFile = "c:\Work.AU3\oem\oeminfo.ini"
$sLine = 'Line1="Телефоны службы технической поддержки:"'

$sText = FileRead($sFile)

If StringLeft($sText, 2) <> @CRLF Then $sText = @CRLF & $sText
If StringRight($sText, 2) <> @CRLF Then $sText &= @CRLF

$sText = StringRegExpReplace($sText, "(?i)\r\n" & $sLine & "\r\n", "")

If StringLeft($sText, 2) == @CRLF Then $sText = StringTrimLeft($sText, 2)
If StringRight($sText, 2) == @CRLF Then $sText = StringTrimRight($sText, 2)

FileDelete($sFile)
FileWrite($sFile, $sText)


amel27 08-04-2009 12:16 1087763

Цитата:

Цитата proxy
тогда уж так »

а надо ли усложнять?.. первой она не может быть (имя секции), последней маловероятно - оставлять "висячие строки" без завершающего CRLF как-то не принято, тем более в системных файлах... кста, твой вариант "слепит" предыдущую и последующую строки (между ними удалены все разделители) + не учтены возможные спецсимволы движка RegExp в искомой строке... ;)

proxy 08-04-2009 17:22 1088074

Цитата:

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

Цитата:

первой она не может быть (имя секции)
и структура файла, даже ini может быть не стандартная...это ж только пример ..)

Цитата:

последней маловероятно - оставлять "висячие строки" без завершающего CRLF как-то не принято, тем более в системных файлах
...не совсем понял, по идее все что добавил вручную, то и удалится...

Цитата:

кста, твой вариант "слепит" предыдущую и последующую строки (между ними удалены все разделители)
где удалются? ...если конечно не добавил уменьшение жадности в паттерн....но на тестах работало приавильно ))

Цитата:

не учтены возможные спецсимволы движка RegExp в искомой строке
на то он и пример, а не конечная UDF )))) не совсем разобрался в переводе, это делает: \Q...\E ?
или только вручную, меня всякие \ на \\ и т.д.?

Pozia 08-04-2009 18:37 1088145

proxy, amel27, в общем такой вот имею ini файл:

Код:

[General]
Manufacturer=Windows XP Pozia Edition 2009
Model=NVIDIA GeForce 9800 GT 
[OEMSpecific]
SerialNo="xxxxx-xxxxx-xxxxx-xxxxx-xxxxx"
[Support Information]
Line1=ОС: Windows XP SP 3 версия 5.1 сборка 2600.xpsp_sp3_qfe.080814-1300
Line2=
Line3=--------------------------------------------------------------------------------
Line4=Дата и время установки: 07.04.2009 (23:11)
Line5=--------------------------------------------------------------------------------
Line6=По любым вопросам и предложениям можно обратиться:
Line7=Velcom: x-xxx-xxx-xx-xx
Line8=MTC:    x-xxx-xxx-xx-xx
Line9=ICQ:    xxx-xxx-xxx
Line10=Mail:      xxxxx@xxxxxx.xx
Line11= xxxxxx xxxxxx xxxxxxxxxxx
Line12=--------------------------------------------------------------------------------
Line13=
Line14=Установленные компоненты и обновления (78):
Line15=
Line16=BASECSP  DNet1135  Games    IE8      IE968220  KB887606
Line17=KB922120  KB928788  KB929399  KB929773  KB932390  KB932716
Line18=KB933547  KB935551  KB935552  KB935957  KB939209  KB939683
Line19=KB941569  KB942288  KB943729  KB944043  KB946648  KB950762
Line20=KB950974  KB951066  KB951376  KB951618  KB951698  KB951748
Line21=KB951830  KB951978  KB952011  KB952069  KB952287  KB952954
Line22=KB953155  KB954067  KB954154  KB954459  KB954600  KB954708
Line23=KB954920  KB955069  KB955417  KB955704  KB955839  KB956802
Line24=KB956841  KB957097  KB958644  KB958655  KB958687  KB958690
Line25=KB958752  KB959772  KB960225  KB960680  KB960763  MSCOMPPA
Line26=MSXML    MassStor  OEMINFO  Patch_NT  Patch_NT  Patch_NT
Line27=Patch_NT  ROOTSUPD  SetupPro  SetupSet  WInstyle  WMFDIST1
Line28=WMP11    WMP11RU  WPI      WSTART    WSidebar  WUDF0100

В идиале нужно сделать так:

Код:

[General]
Manufacturer=Windows XP Pozia Edition 2009
Model=NVIDIA GeForce 9800 GT 
[OEMSpecific]
SerialNo="xxxxx-xxxxx-xxxxx-xxxxx-xxxxx"
[Support Information]
Line1=ОС: Windows XP SP 3 версия 5.1 сборка 2600.xpsp_sp3_qfe.080814-1300
Line2=
Line3=--------------------------------------------------------------------------------
Line4=Дата и время установки: 07.04.2009 (23:11)
Line5=--------------------------------------------------------------------------------
Line6=По любым вопросам и предложениям можно обратиться:
Line7=Velcom: x-xxx-xxx-xx-xx
Line8=MTC:    x-xxx-xxx-xx-xx
Line9=ICQ:    xxx-xxx-xxx
Line10=Mail:      xxxxx@xxxxxx.xx
Line11= xxxxxx xxxxxx xxxxxxxxxxx
Line12=--------------------------------------------------------------------------------
Line13=
Line14=Установленные компоненты и обновления (54):
Line15=
Line16=KB922120  KB928788  KB929399  KB929773  KB932390  KB932716
Line17=KB933547  KB935551  KB935552  KB935957  KB939209  KB939683
Line18=KB941569  KB942288  KB943729  KB944043  KB946648  KB950762
Line19=KB950974  KB951066  KB951376  KB951618  KB951698  KB951748
Line20=KB951830  KB951978  KB952011  KB952069  KB952287  KB952954
Line21=KB953155  KB954067  KB954154  KB954459  KB954600  KB954708
Line22=KB954920  KB955069  KB955417  KB955704  KB955839  KB956802
Line23=KB956841  KB957097  KB958644  KB958655  KB958687  KB958690
Line24=KB958752  KB959772  KB960225  KB960680  KB960763  KB887606

То есть мне нужно оставить только обнавления вида KB****** и пересчитать количество обнавлений. Так возможно?

proxy 08-04-2009 20:48 1088252

Код:

;~ #NoTrayIcon

#region: - Options
    Opt('GUIOnEventMode',      1)
    Opt('MustDeclareVars',      1)
    Opt('TrayIconDebug',        1)
    Opt('TrayIconHide',        0)
#endregion

Local  $sFilePath = @ScriptDir & '\oeminfo.ini'

Local  $sResult = _EditOemInfo($sFilePath, 0)
If @error Then
    MsgBox(16, 'Ошибка', $sResult & @CRLF & @CRLF & 'Колличество КВ:' & @TAB & @extended & @CRLF & 'Код результата:' & @TAB & @error)
Else
    MsgBox(64, 'Результат', $sResult & @CRLF & @CRLF & 'Колличество КВ:' & @TAB & @extended & @CRLF & 'Код результата:' & @TAB & @error)
EndIf

Func
_EditOemInfo($sFilePath, $iCountKbRow)
    Local  $sFileText = FileRead($sFilePath)
            If @error Then Return SetError(1, 0, 'Ошибка чтения файла')

    Local  $aKB = StringRegExp($sFileText, '(?s)(KB\d+)', 3)
            If @error Then Return SetError(2, 0, 'Ошибка поиска KB')

    Local  $iLineNamber = StringRegExpReplace($sFileText, '(?i)(?s).*Line(\d+)=Установленные компоненты и обновления.*', '\1') + 1
            If @error Then Return SetError(3, 0, 'Ошибка определения номера Line')

    Local  $sKB = 'Line' & $iLineNamber & '=' & @CRLF
    Local  $n, $i

    If $iCountKbRow < 1 Then $iCountKbRow = 4

    For $i=0 To UBound($aKB)
        $iLineNamber += 1
        $sKB &= 'Line' & $iLineNamber & '='
        For $n=0 To $iCountKbRow-1
            If $i+$n >= UBound($aKB) Then ExitLoop 2
            $sKB &= $aKB[$i+$n]
            If $n < $iCountKbRow-1 Then
                $sKB &= ' '
            Else
                $sKB &= @CRLF
                $i += $iCountKbRow-1
            EndIf
        Next
        If
$i >= UBound($aKB)-1 Then ExitLoop
    Next

    If
StringRight($sKB, 1) == ' ' Then $sKB = StringTrimRight($sKB, 1)
    If StringRight($sKB, 2) == @CRLF Then $sKB = StringTrimRight($sKB, 2)

    $sFileText = StringRegExpReplace($sFileText, '(?i)(?s)(.*Установленные компоненты и обновления).*', '\1') & ' (' & UBound($aKB) & '):' & @CRLF & $sKB

    FileDelete($sFilePath)
    FileWrite($sFilePath, $sFileText)

    Return SetError(0, UBound($aKB), 'Операция выполненна успешно')
EndFunc


Pozia 08-04-2009 21:30 1088287

proxy, спасибо! есть один глюк. скрипт глотает некоторые KB***
После выполнения пересчитал правильно - 54 но их получилось в ini файле 44. Посмотрите пожалуйста ошибку. И сделайте пожалуйста скрипт полностью тихим. Не нужно всяких окон о выполнении

И в исходном файле 6 столбцов обнавлений. После обработки получается 4. Подправте тоже пожалуйста

proxy 08-04-2009 21:54 1088304

1. Перепроверьте скрипт, тогда его обновлял. У меня все работае отлично.
2. Стоит "читать" код - там все есть: _EditOemInfo($sFilePath, $iCountKbRow)
$iCountKbRow - колличество KB столбцов, не сложно догадаться/перевести...
Волшебная строка: _EditOemInfo($sFilePath, 0) - меняйте ноль на колличество желаемых столбцов.
3.
Цитата:

И сделайте пожалуйста скрипт полностью тихим. Не нужно всяких окон о выполнении
Закомментируйте функции вывода сообщений.

Pozia 08-04-2009 22:32 1088345

proxy, а как добавить пробелов между KB***?
Сильно не пинайте, я ноль в скриптах(

proxy 08-04-2009 23:19 1088390

увиличивайте колличество пробелов вот тут:
Код:

.....
If $n < $iCountKbRow-1 Then
    $sKB &= ' '
Else
......

Цитата:

Сильно не пинайте, я ноль в скриптах
Учится ни когда не поздно ))

amel27 09-04-2009 06:58 1088541

вариант через RegExp():
Код:

$sFile = "c:\Work.AU3\oem\OEMInfo.ini"
$sText= FileRead($sFile)

$aTag = StringRegExp($sText, "(?ism)^Line(\d+)=Установленные компоненты и обновления \(\d+\):", 3)
$iTag = StringInStr ($sText, @CRLF&"Line"& $aTag[0] &"=")+1
$aKBs = StringRegExp($sText, "(?i)\b(KB\d+)\b", 3, $iTag)

$sList = "Line"& $aTag[0] &"=Установленные компоненты и обновления ("& UBound($aKBs) &"):"&@CRLF&"Line"& $aTag[0]+1 &"="& @CRLF
For $i=0 To UBound($aKBs)-1 Step 6
    $sList &= StringFormat("Line%-i=%-10s%-10s%-10s%-10s%-10s%-10s\r\n",$aTag[0]+2+$i/6,$aKBs[$i],$aKBs[$i+1],$aKBs[$i+2],$aKBs[$i+3],$aKBs[$i+4],$aKBs[$i+5])
Next

FileDelete($sFile)
FileWrite($sFile,StringLeft($sText,$iTag) & $sList)


Pozia 09-04-2009 07:38 1088548

amel27, спасибо. Вечером проверю ваш вариант

proxy 09-04-2009 08:00 1088556

amel27, StringFormat (!!!!) блин....как все просто!! )))
Цитата:

For $i=0 To UBound($aKBs)-1 Step 6
$sList &= StringFormat("Line%-i=%-10s%-10s%-10s%-10s%-10s%-10s\r\n",$aTag[0]+2+$i/6,$aKBs[$i],$aKBs[$i+1],$aKBs[$i+2],$aKBs[$i+3],$aKBs[$i+4],$aKBs[$i+5])
Next
супер

Pozia 09-04-2009 18:18 1089092

amel27, ВЫ как всегда на высоте. Кратко, быстро и по делу. Вот только не могу сообразить что поменять чтобы стало колонок допустим 5 и интервал между ними 7 пробелов. Подскажите пожалуйста

amel27 10-04-2009 04:32 1089555

Цитата:

Цитата Pozia
ВЫ как всегда на высоте »

не расслабляйтесь, в предыдущем скрипте есть ошибка :ohmy:

Цитата:

Цитата Pozia
что поменять чтобы стало колонок допустим 5 и интервал между ними 7 пробелов »

Код:

_OEM_KBFormat("c:\Work.AU3\oem\OEMInfo.ini", 5, 15)

Func _OEM_KBFormat($sFile, $iCols = 6, $iTabs = 10)
    Local $sTXT = FileRead($sFile)
    If @error Then Return SetError(1)
    Local $aTag = StringRegExp($sTXT, "(?ism)^Line(\d+)=Установленные компоненты и обновления \(\d+\):", 3)
    If IsArray($aTag)=0 Then Return SetError(2)
    Local $iTag = StringInStr ($sTXT, @CRLF&"Line"& $aTag[0] &"=")+1
    Local $aKBs = StringRegExp($sTXT, "(?i)\b(KB\d+)\b", 3, $iTag)
    If IsArray($aKBs) Then
        Local
$sList = "Line"& $aTag[0] &"=Установленные компоненты и обновления ("& UBound($aKBs) &"):"&@CRLF&"Line"& $aTag[0]+1 &"="& @CRLF
        For $i=0 To UBound($aKBs)-1 Step $iCols
            Local $sExecL="", $sExecR=""
            For $j=0 To $iCols-1
                If $j<$iCols-1 Then $sExecL &= '%-'& $iTabs &'s'
                If $i+$j<UBound($aKBs) Then $sExecR &= ',$aKBs[$i+'& $j &']'
            Next
            $sList &= Execute('StringFormat("Line%-i='& $sExecL &'%s\r\n",$aTag[0]+2+$i/'& $iCols & $sExecR &')')
        Next
        FileDelete($sFile)
        FileWrite($sFile,StringLeft($sTXT,$iTag) & $sList)
        If @error Then Return SetError(3)
    EndIf
EndFunc


Pozia 10-04-2009 07:47 1089597

Цитата:

Цитата amel27
не расслабляйтесь, в предыдущем скрипте есть ошибка »

не знаю в чем ошибка но все работает

за новый скрипт спасибо, сообразил что менять

amel27 10-04-2009 08:10 1089617

Цитата:

Цитата Pozia
не знаю в чем ошибка »

не работает, если последняя строка заполнена не до конца

Pozia 27-10-2009 18:42 1254018

amel27, прошу Вас подправить скрипт чтобы он помимо KB*.* оставлял следующие файлы:

BASECSP.CA_
IE*
MSCMPACK.CA_
WM*
WM*
WU*


Время: 15:19.

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