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

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

ul9 09-11-2013 01:33 2250455

Замена текста в интервалах
 
Здравствуйте.
Нуждаюсь в вашей помощи.
Нашла такой скрипт.
Код:

Option Explicit

Const ForReading  = 1
Const ForWriting  = 2


Dim objArgs
Dim objFSO
Dim objFile

Dim strWhatFind
Dim strReplaceBy

Dim strContent


Set objArgs = WScript.Arguments.Named

If objArgs.Count = 4 Then
    Set objFSO  = WScript.CreateObject("Scripting.FileSystemObject")
   
    If objArgs.Exists("FolderForScan") Then
        If objArgs.Exists("FileExtension") Then
            If objArgs.Exists("FileWhatFind") Then
                If objArgs.Exists("FileReplaceBy") Then
                    If objFSO.FolderExists(objArgs.Item("FolderForScan")) Then
                        If objFSO.FileExists(objArgs.Item("FileWhatFind")) Then
                            If objFSO.FileExists(objArgs.Item("FileReplaceBy")) Then
                                If objFSO.GetFile(objArgs.Item("FileWhatFind")).Size > 0 Then
                                    With objFSO.OpenTextFile(objArgs.Item("FileWhatFind"), ForReading)
                                        strWhatFind = .ReadAll()
                                        .Close
                                    End With
                                   
                                    If objFSO.GetFile(objArgs.Item("FileReplaceBy")).Size > 0 Then
                                        With objFSO.OpenTextFile(objArgs.Item("FileReplaceBy"), ForReading)
                                            strReplaceBy = .ReadAll()
                                            .Close
                                        End With
                                    Else
                                        strReplaceBy = ""
                                    End If
                                   
                                    WScript.Echo "Folder for scan: " & objArgs.Item("FolderForScan")
                                    WScript.Echo "File extension:  " & objArgs.Item("FileExtension")
                                    WScript.Echo "File what find:  " & objArgs.Item("FileWhatFind")
                                    WScript.Echo "File replace by: " & objArgs.Item("FileReplaceBy")
                                    WScript.Echo
                                   
                                    ScanSubFolders objFSO.GetFolder(objArgs.Item("FolderForScan"))
                                Else
                                    WScript.Echo "File [" & objArgs.Item("FileWhatFind") & "] is zero length"
                                End If
                            Else
                                WScript.Echo "File [" & objArgs.Item("FileWhatFind") & "] not found"
                            End If
                        Else
                            WScript.Echo "File [" & objArgs.Item("FileWhatFind") & "] not found"
                        End If
                    Else
                        WScript.Echo "Folder [" & objArgs.Item("FolderForScan") & "] not found"
                    End If
                Else
                    WScript.Echo "Not found argument <FileReplaceBy>"
                    Call Usage
                End If
            Else
                WScript.Echo "Not found argument <FileWhatFind>"
                Call Usage
            End If
        Else
            WScript.Echo "Not found argument <FileExtension>"
            Call Usage
        End If
    Else
        WScript.Echo "Not found argument <FolderForScan>"
        Call Usage
    End If
   
    Set objFSO = Nothing
Else
    Call Usage
End If

Set objArgs = Nothing

WScript.Quit
'=============================================================================

'=============================================================================
Sub ScanSubFolders(objFolder)
    Dim objSubFolder
    Dim objFile
   
    WScript.Echo "[" & objFolder.Path & "]"
   
    For Each objFile In objFolder.Files
        If UCase(objFSO.GetExtensionName(objFile.Name)) = UCase(objArgs.Item("FileExtension")) Then
            WScript.Echo "  " & objFile.Name
           
            If objFile.Size > 0 Then
                With objFSO.OpenTextFile(objFile.Path, ForReading)
                    strContent = .ReadAll()
                    .Close
                End With
               
                If InStr(1, strContent, strWhatFind, vbTextCompare) > 0 Then
                    WScript.Echo "    Fragment for replace found"
                   
                    With objFSO.OpenTextFile(objFile.Path, ForWriting)
                        .Write Replace(strContent, strWhatFind, strReplaceBy)
                        .Close
                    End With
                End If
            End If
        End If
    Next
   
    WScript.Echo
   
    For Each objSubFolder In objFolder.SubFolders
        ScanSubFolders objSubFolder
    Next
End Sub
'=============================================================================

'=============================================================================
Sub Usage()
    WScript.Echo "Usage: cscript.exe //nologo " & WScript.ScriptName & " " & _
        "/FolderForScan:<folder> " & _
        "/FileExtension:<extension> " & _
        "/FileWhatFind:<file> " & _
        "/FileReplaceBy:<file>"
End Sub
'=============================================================================

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

Пример.
HTML код:

<table>
    <tr><td class="thead">Панель управления</a></td></tr>
    <tr><td class="vbmenu_option">Редактировать подпись</a></td></tr>
    <tr><td class="vbmenu_option">Редактировать профиль</a></td></tr>
    <tr><td class="vbmenu_option">Настройки форума</a></td></tr>

.......................
.......Какой-то html код..........
.......................

    <tr><td class="thead">Разное</td></tr>
    <tr><td class="vbmenu_option">Личные сообщения</a></td></tr>
    <tr><td class="vbmenu_option">Менеджер подписки</a></td></tr>
    <tr><td class="vbmenu_option">Профиль</a></td></tr>
    <tr><td class="vbmenu_option">Пользователи в on-line</a></td></tr>
</table>

скрипт берёт начало <tr><td class="vbmenu_option">Настройки форума</a></td></tr>
скрипт берёт конец <tr><td class="thead">Разное</td></tr>
заменяет информацию, которая находится между этими строками.

Помогите пожалуйста.

ul9 09-11-2013 22:22 2250876

Не тот уже oszone... Не хотят помогать :(

Foreigner 10-11-2013 09:48 2251110

На PowerShell:
Код:

$a = gc 1.txt  # 1.txt исходный файл
$b = gc 2.txt  # 2.txt файл из которого вставляется содержимое
$c = 0

switch -regex ($a) {

    'Настройки форума' { $head = $c ++ }
    'Разное'          { $foot = $c ++; break }
    default            { $c ++ }

}

$a[0..$head], $b, $a[$foot..($a.count - 1)] | sc 1.txt


ul9 10-11-2013 18:00 2251370

Здесь задаётся в коде условие.
А можно, чтобы условия поиска он брал из txt файла. Т.к. замен будет много, а мне нужен универсальный скрипт, которому я буду подсовывать только условия поиска.

morebeauty 12-11-2013 11:00 2252651

Цитата:

Цитата ul9
"vbmenu_option" »

А не vBulletin ли это? Если так, то к нему есть модуль для пропатчивания, который как раз и выполняет нужную вам задачу. Лень сейчас гуглить, когда то им пользовался (лет 10 назад).

ul9 12-11-2013 21:21 2253176

Цитата:

Цитата morebeauty
А не vBulletin ли это? Если так, то к нему есть модуль для пропатчивания, который как раз и выполняет нужную вам задачу. Лень сейчас гуглить, когда то им пользовался (лет 10 назад). »

Нет, это просто пример. Работа ведётся с html файлами, локально.

morebeauty 13-11-2013 05:20 2253401

Понятно. Исправил предложенный тобой скрипт.
Не тестировал, поэтому первый запуск советую произвести на тестовой папке с копиями реальных файлов. В теории все должно работать :)
Если чего то работать не будет или будет работать не так, опиши подробно что не так.
Перед использованием читай описание внизу сообщения.

Код:

Option Explicit

Const ForReading  = 1
Const ForWriting  = 2


Dim objArgs
Dim objFSO
Dim objFile

Dim strWhatFind
Dim strReplaceBy
Dim strFindFrom
Dim strFindTo
Dim strContent


Set objArgs = WScript.Arguments.Named

If objArgs.Count = 5 Then
    Set objFSO  = WScript.CreateObject("Scripting.FileSystemObject")
   
    If objArgs.Exists("FolderForScan") Then
        If objArgs.Exists("FileExtension") Then
            If objArgs.Exists("FileReplaceBy") Then
                If objArgs.Exists("FileFindFrom") Then
                        If objArgs.Exists("FileFindTo") Then
                                If objFSO.FolderExists(objArgs.Item("FolderForScan")) Then
                                        If objFSO.FileExists(objArgs.Item("FileFindFrom")) Then
                                                If objFSO.FileExists(objArgs.Item("FileFindTo")) Then
                                                        If objFSO.FileExists(objArgs.Item("FileReplaceBy")) Then

                                                                If objFSO.GetFile(objArgs.Item("FileFindFrom")).Size > 0 Then
                                                                        With objFSO.OpenTextFile(objArgs.Item("FileFindFrom"), ForReading)
                                                                                strFindFrom = .ReadAll()
                                                                                .Close
                                                                        End With
                                                                Else
                                                                        strFindFrom = ""
                                                                End If
                                                                If objFSO.GetFile(objArgs.Item("FileFindTo")).Size > 0 Then
                                                                        With objFSO.OpenTextFile(objArgs.Item("FileFindTo"), ForReading)
                                                                                strFindTo = .ReadAll()
                                                                                .Close
                                                                        End With
                                                                Else
                                                                        strFindTo = ""
                                                                End If
                                                                               
                                                                If objFSO.GetFile(objArgs.Item("FileReplaceBy")).Size > 0 Then
                                                                        With objFSO.OpenTextFile(objArgs.Item("FileReplaceBy"), ForReading)
                                                                                strReplaceBy = .ReadAll()
                                                                                .Close
                                                                        End With
                                                                Else
                                                                        strReplaceBy = ""
                                                                End If
                                                                               
                                                                WScript.Echo "Folder for scan: " & objArgs.Item("FolderForScan")
                                                                WScript.Echo "File extension:  " & objArgs.Item("FileExtension")
                                                                WScript.Echo "File find from:  " & objArgs.Item("FileFindFrom")
                                                                WScript.Echo "File find to:    " & objArgs.Item("FileFindto")
                                                                WScript.Echo "File replace by: " & objArgs.Item("FileReplaceBy")
                                                                WScript.Echo
                                                                               
                                                                ScanSubFolders objFSO.GetFolder(objArgs.Item("FolderForScan"))

                                                        Else
                                                                WScript.Echo "File [" & objArgs.Item("FileReplaceBy") & "] not found"
                                                        End If
                                                Else
                                                        WScript.Echo "File [" & objArgs.Item("FileFindTo") & "] not found"
                                                End If
                                        Else
                                                WScript.Echo "File [" & objArgs.Item("FileFindFrom") & "] not found"
                                        End If
                                Else
                                        WScript.Echo "Folder [" & objArgs.Item("FolderForScan") & "] not found"
                                End If
                        Else
                                WScript.Echo "Not found argument <FileFindTo>"
                                Call Usage                                       
                        End If
                Else
                    WScript.Echo "Not found argument <FileFindFrom>"
                    Call Usage
                End If
            Else
                WScript.Echo "Not found argument <FileReplaceBy>"
                Call Usage
            End If
        Else
            WScript.Echo "Not found argument <FileExtension>"
            Call Usage
        End If
    Else
        WScript.Echo "Not found argument <FolderForScan>"
        Call Usage
    End If
   
    Set objFSO = Nothing
Else
    Call Usage
End If

Set objArgs = Nothing

WScript.Quit
'=============================================================================

'=============================================================================
Sub ScanSubFolders(objFolder)
    Dim objSubFolder
    Dim objFile
   
    WScript.Echo "[" & objFolder.Path & "]"
   
    For Each objFile In objFolder.Files
        If UCase(objFSO.GetExtensionName(objFile.Name)) = UCase(objArgs.Item("FileExtension")) Then
            WScript.Echo "  " & objFile.Name
           
            If objFile.Size > 0 Then
                With objFSO.OpenTextFile(objFile.Path, ForReading)
                    strContent = .ReadAll()
                    .Close
                End With
                Dim posFrom As Currency
                Dim posTo As Currency
                If strFindFrom > "" And strFindTo > "" Then
                        posFrom = InStr(1, strContent, strFindFrom, vbTextCompare) + Len(strFindFrom)
                        posTo = InStr(1, strContent, strFindTo, vbTextCompare)
                Else
                        If strFindFrom > "" And strFindTo = "" Then
                                posFrom = InStr(1, strContent, strFindFrom, vbTextCompare) + Len(strFindFrom)
                                posTo = Len(strContent)                                       
                        End If
                        If strFindFrom = "" And strFindTo > "" Then
                                posFrom = 1
                                posTo = InStr(1, strContent, strFindTo, vbTextCompare)                                       
                        End if
                        If strFindFrom = "" And strFindTo = "" Then
                                posFrom = 0
                                posTo = 0                                       
                        End if
                End If
                If posFrom > Len(strFindFrom) And posTo > 0 Then
                        strWhatFind = Mid(strContent, posFrom,  posTo - posFrom)
                Else
                        strWhatFind = ""
                End If
                If InStr(1, strContent, strWhatFind, vbTextCompare) > 0 Then
                    WScript.Echo "    Fragment for replace found"
                   
                    With objFSO.OpenTextFile(objFile.Path, ForWriting)
                        .Write Replace(strContent, strWhatFind, strReplaceBy)
                        .Close
                    End With
                End If
            End If
        End If
    Next
   
    WScript.Echo
   
    For Each objSubFolder In objFolder.SubFolders
        ScanSubFolders objSubFolder
    Next
End Sub
'=============================================================================

'=============================================================================
Sub Usage()
    WScript.Echo "Usage: cscript.exe //nologo " & WScript.ScriptName & " " & _
        "/FolderForScan:<folder> " & _
        "/FileExtension:<extension> " & _
        "/FileWhatFind:<file> " & _
        "/FileReplaceBy:<file>"
End Sub

Описание:
Теперь скрипт нужно запускать не с 4 параметрами, а с 5.
  1. FolderForScan - был
  2. FileExtension - был
  3. FileReplaceBy - был
  4. FileFindFrom - новый параметр. Строка от которой нужно произвести замену (не включая саму строку)
  5. FileFindTo - новый параметр. Строка до которой нужно произвести замену (не включая саму строку)

Соответственно файлов с информацией теперь будет 3:
  1. Файл со строкой начала
  2. Файл со строкой конца
  3. Файл с текстом для замены

Условия выполнения замены (важно):
Если в файле начальной строки и в файле конечной строки есть информация и она найдена в тексте, то будет произведена обычная заменя ОТ -- ДО
Если в файле начальной строки ничего нет, а в файле конечной строки есть информация и она найдена, то будет произведена замена с самого начала файла до конечной строки
Если в файле начальной строки есть информация и она найдена, а в файле конечной строки ничего нет, то будет произведена замена от начальной строки до конца файла

ul9 13-11-2013 18:23 2253828

Ага, спасибо! А как всю эту прелесть вызывать теперь?
Раньше вот так вызывала.
Код:

cscript.exe //nologo replace.vbs /FolderForScan:"%UserProfile%\Рабочий стол\work" /FileExtension:"html" /FileWhatFind:"text\art_s.txt" /FileReplaceBy:"text\art_r.txt"

ul9 13-11-2013 22:12 2254005

Запустила вот так
Код:

cscript.exe //nologo from_to.vbs /FolderForScan:"C:\from_to" /FileExtension:"html" /FileReplaceBy:"text\FileReplaceBy.txt" /FileFindFrom:"text\FileFindFrom.txt" /FileFindTo:"text\FileFindTo.txt"
Выдало ошибку
C:\from_to\from_to.vbs(127, 29) Ошибка компиляции Microsoft vbscript: Предполагается наличие окончания инструкции

morebeauty 14-11-2013 07:14 2254173

Все правильно, это же VBS тут нельзя указывать типы переменных :)
Исправьте
Dim posFrom As Currency
Dim posTo As Currency


на
Dim posFrom
Dim posTo


в скрипте и попробуйте еще

ul9 15-11-2013 02:42 2254914

Цитата:

Цитата morebeauty
это же VBS тут нельзя указывать типы переменных »

Точно, как же я забыла об этом :teeth:
Цитата:

Цитата morebeauty
Исправьте »

Спасибо, теперь всё заработало!

Только есть небольшие мелочи, которые хотелось бы добавить:
- если совпадение from или to не найдено, то скрипт выдаёт MsgBox с ошибкой, указывая на файл, при этом прекращает дальнейшую работу.

morebeauty 15-11-2013 04:54 2254931

Цитата:

Цитата ul9
- если совпадение from или to не найдено, то скрипт выдаёт MsgBox с ошибкой, указывая на файл, при этом прекращает дальнейшую работу. »

А какое именно сообщение?

Сообщение он должен выводить, если не найден один из файлов. Так задумано. Однако FintTo или FindFrom можно оставить пустыми. при этом сами файлы должны существовать.

Хотя исправь в скрипте вот эту строку

If posFrom > Len(strFindFrom) And posTo > 0 Then

на

If posFrom > Len(strFindFrom) Or posTo > 0 Then

ul9 16-11-2013 02:20 2255642

Сейчас он выдаёт такую ошибку, если не найдено совпадение конца поиска (strFindTo)
C:\from_to\from_to.vbs(147, 4) Ошибка выполнения Microsoft vbscript: Недопустимый вызов или аргумент процедуры: 'Mid'

Если не найдено совпадение начала поиска (strFindFrom), то оно просто заменяет от начала документа до конца поиска (strFindTo).
Цитата:

Цитата morebeauty
Хотя исправь в скрипте вот эту строку
If posFrom > Len(strFindFrom) And posTo > 0 Then
на
If posFrom > Len(strFindFrom) Or posTo > 0 Then »

Вернула обратно.
Цитата:

Цитата morebeauty
А какое именно сообщение? »

Название файла, в котором не нашёл совпадение и кнопочку "ок". Но при этом предупреждении скрипт становится на пауза, после нажатия "ок" скрипт продолжает замены.


Время: 07:39.

Время: 07:39.
© OSzone.net 2001-