Войти

Показать полную графическую версию : [решено] Замена текста в интервалах


ul9
09-11-2013, 01:33
Здравствуйте.
Нуждаюсь в вашей помощи.
Нашла такой скрипт.
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
'=============================================================================Он находит точное совпадение из одного файла и меняет на информацию, взятую из другого файла.
Можно его как-нибудь модифицировать, чтобы он искал начало и конец, а всё что в промежутке заменял?

Пример.
<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
Не тот уже oszone... Не хотят помогать :(

Foreigner
10-11-2013, 09:48
На 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
Здесь задаётся в коде условие.
А можно, чтобы условия поиска он брал из txt файла. Т.к. замен будет много, а мне нужен универсальный скрипт, которому я буду подсовывать только условия поиска.

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

ul9
12-11-2013, 21:21
А не vBulletin ли это? Если так, то к нему есть модуль для пропатчивания, который как раз и выполняет нужную вам задачу. Лень сейчас гуглить, когда то им пользовался (лет 10 назад). »
Нет, это просто пример. Работа ведётся с html файлами, локально.

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


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.

FolderForScan - был
FileExtension - был
FileReplaceBy - был
FileFindFrom - новый параметр. Строка от которой нужно произвести замену (не включая саму строку)
FileFindTo - новый параметр. Строка до которой нужно произвести замену (не включая саму строку)


Соответственно файлов с информацией теперь будет 3:

Файл со строкой начала
Файл со строкой конца
Файл с текстом для замены


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

ul9
13-11-2013, 18:23
Ага, спасибо! А как всю эту прелесть вызывать теперь?
Раньше вот так вызывала.
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
Запустила вот так
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
Все правильно, это же VBS тут нельзя указывать типы переменных :)
Исправьте
Dim posFrom As Currency
Dim posTo As Currency

на
Dim posFrom
Dim posTo

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

ul9
15-11-2013, 02:42
это же VBS тут нельзя указывать типы переменных »
Точно, как же я забыла об этом :teeth:
Исправьте »
Спасибо, теперь всё заработало!

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

morebeauty
15-11-2013, 04:54
- если совпадение 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
Сейчас он выдаёт такую ошибку, если не найдено совпадение конца поиска (strFindTo)
C:\from_to\from_to.vbs(147, 4) Ошибка выполнения Microsoft VBScript: Недопустимый вызов или аргумент процедуры: 'Mid'

Если не найдено совпадение начала поиска (strFindFrom), то оно просто заменяет от начала документа до конца поиска (strFindTo).
Хотя исправь в скрипте вот эту строку
If posFrom > Len(strFindFrom) And posTo > 0 Then
на
If posFrom > Len(strFindFrom) Or posTo > 0 Then »
Вернула обратно.
А какое именно сообщение? »
Название файла, в котором не нашёл совпадение и кнопочку "ок". Но при этом предупреждении скрипт становится на пауза, после нажатия "ок" скрипт продолжает замены.




© OSzone.net 2001-2012