1 (изменено: griha09, 2012-09-02 14:50:24)

Тема: VBS: поиск в строке и удаление этой строки

есть скрипт который в каждом файле папки ищет  строку с заданным словом word и удаляет эту строку, но он удаляет только  строку с первым искомым словом в файле, а остальные оставляет. Вот никак не могу придумать как переделать его чтоб удалял строки со всеми искомыми словами в файле.

word = "Source:"                 'искомое слово
papka = "c:\temp\"            'папка поиска
otchet = "D:\\временное\\WSH\\test\\otchet.txt"        'файл отчета
i=0

Dim boolFound



Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objRegExp = CreateObject("VBScript.RegExp")
objRegExp.IgnoreCase = True
Set file2 = objFSO.OpenTextFile(otchet, 2, True)  '2 - Открыть файл для записи. Если файл уже существовал, его содержимое теряется. 8 - Открыть файл для добавления. Если файл уже существовал, информация будет дописываться в конец файла.Создавать файл, если он не существует (True), или нет (False). 


RecursiveFolderScan papka
file2.close

Msgbox "ВСЕ! Обработано "& i &" файлов"



Sub RecursiveFolderScan(FolderPath)
    'Получаем объектную модель текущего каталога
    Set Folder = objFSO.GetFolder(FolderPath)
 
    'Перебираем все файлы в текущем каталоге
    For Each File in Folder.Files

Set file1 = objFSO.OpenTextFile(File, 1, False)
boolFound = False

Do Until file1.AtEndOfStream
sw = file1.ReadLine()

If InStr(1, sw, word) <> 0 Then
                boolFound = True
file2.WriteLine(file.Name)         
file2.WriteLine(sw)     
                Exit Do
            End If
        Loop
file1.close
 

'записать уникальный номер в конец исходной страницы
    If boolFound Then
Set file1 = objFSO.OpenTextFile(File, 1, False)
strText = file1.ReadAll
file1.close
strNewText = Replace(strText, sw, " ")          
                                      
Set file1 = objFSO.OpenTextFile(File, 2, False)
file1.WriteLine strNewText
file1.close

    End If


i=i+1        'счетчик файлов




    Next
 
    'Перебираем все подкаталоги в каталоге
    For Each SubFolder in Folder.SubFolders
        RecursiveFolderScan(SubFolder.Path)
    Next
End Sub

2

Re: VBS: поиск в строке и удаление этой строки

RegExp

3 (изменено: Rumata, 2012-09-02 16:30:53)

Re: VBS: поиск в строке и удаление этой строки

griha09
Опишу алгоритм словесно. Полагаю, что по нему реализацию Вы осилите. Будут вопросы - задавайте.

получить список файлов в переменную files

for each file in files
    create tempfile // создать временный файл и открыть на запись
    file.open // открыть файл на чтение
    while not EOF file
        line = file.ReadLine
        if line содержит заданную подстроку then
            выполнить какие-то действия (например, запись в лог-файл о нахождении заданной подстроки)
            пропустить, перейти к следующей строке
        end if
        tempfile.WriteLine line // сохранить строку во временном файле
    end while
    file.Close // закрыть файл
    tempfile.Close // закрыть временный файл
    rename tempfile file // переименовать временный файл в файл
end for
( 2 * b ) || ! ( 2 * b )

4

Re: VBS: поиск в строке и удаление этой строки

Rumata
вообще-то мне надо удалить все строки (заменить на " "), содержащие заданную подстроку, а не сохранить их в др.файл. А могу,  конечно, записать в др. файл строки не содержащие заданную подстроку, но тут уже просто интересно как модифицировать именно этот скрипт на замену всех строк а не только первой с заданной подстрокой.

5

Re: VBS: поиск в строке и удаление этой строки

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

( 2 * b ) || ! ( 2 * b )

6 (изменено: Flasher, 2012-09-08 19:05:21)

Re: VBS: поиск в строке и удаление этой строки

griha09
Не вдаваясь в технические подробности: нужно не строки в цикле перебирать, а сразу заменять через RegExp.Replace в ReadAll всю комбинацию * искомое слово * vbNewline на " " vbNewline.

7

Re: VBS: поиск в строке и удаление этой строки

Могу читать и писать одновременно - я Юлий Цезарь ?

Я конечно далек от мысли... (с)

8

Re: VBS: поиск в строке и удаление этой строки

Не знаю к чему флуд, но Rumata имел в виду, что после открытия файла на запись читать его уже не имеет смысла (он будет пустовать), поэтому перебирать построчно так не получится. Вот я и пишу что надо запонимать в переменной весь исправленный текст, а потом его целиком записывать.

9

Re: VBS: поиск в строке и удаление этой строки

smaharbA, поясните — при помощи «TextStream»?

10

Re: VBS: поиск в строке и удаление этой строки

smaharbA пишет:

Могу читать и писать одновременно

Коллега, обратите внимание на всю фразу:

Rumata пишет:

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

Flasher
Согласен. Но что будет с очень большими файлами? Не будет ли зависания скрипта или аварийного завершения по нехватке памяти?

( 2 * b ) || ! ( 2 * b )

11

Re: VBS: поиск в строке и удаление этой строки

griha09 пишет:

Вот никак не могу придумать как переделать его чтоб удалял строки со всеми искомыми словами в файле.

Я закомментировал Ваш скрипт таким образом, чтобы дочитав текст скрипта до конца Вы решили вопрос.


word = "Source:" 'искомое слово
papka = "c:\temp\" 'папка поиска

otchet = "otchet.txt" 'файл отчета - поместим его в каталог скрипта для простоты
i = 0 'счетчик файлов

Dim boolFound 'флаг - слово найдено

Set objFSO = CreateObject("Scripting.FileSystemObject")

'---не понял причем тут RegExp
'Set objRegExp = CreateObject("VBScript.RegExp")
'objRegExp.IgnoreCase = True

Set file2 = objFSO.OpenTextFile(otchet, 2, True)

RecursiveFolderScan papka

file2.close

Msgbox "ВСЕ! Обработано "& i &" файлов"



Sub RecursiveFolderScan(FolderPath)
    'Получаем объектную модель текущего каталога
    Set Folder = objFSO.GetFolder(FolderPath)
 
    'Перебираем все файлы в текущем каталоге
    For Each File in Folder.Files

		Set file1 = objFSO.OpenTextFile(File, 1, False) 'читаем файл
		boolFound = False

		Do Until file1.AtEndOfStream
			sw = file1.ReadLine() 'по-строчно
			If InStr(1, sw, word) <> 0 Then
				boolFound = True 'слово найдено
				file2.WriteLine(file.Name) 'пишем в отчет имя файла      
				file2.WriteLine(sw) 'пишем в отчет всю строку
				Exit Do 'выходим из цикла - скрипт пишет в отчет только строку с первым словом
			End If
        Loop
		file1.close 'закрываем файл

		'записать уникальный номер в конец исходной страницы
		If boolFound Then
			Set file1 = objFSO.OpenTextFile(File, 1, False) 'снова читаем тот же файл
			strText = file1.ReadAll 'читаем все содержимое в переменную			
			file1.close 'и опять закрываем
			'меняем все вхождения найденной строки на пробел - а надо наверное искомого слова - word
			strNewText = Replace(strText, sw, " ") 			
			
			'снова открываем тот же файл - на этот раз для записи - таким образом удаляя все содержимое файла
			Set file1 = objFSO.OpenTextFile(File, 2, False)
			file1.WriteLine strNewText 'пишем новое содержимое
			file1.close 'и закрываем в третий раз
		End If	

		i = i + 1 'счетчик файлов
    Next
 
    'Перебираем все подкаталоги в каталоге
    For Each SubFolder in Folder.SubFolders
        RecursiveFolderScan(SubFolder.Path)
    Next
End Sub

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

12 (изменено: Flasher, 2012-09-09 00:58:11)

Re: VBS: поиск в строке и удаление этой строки

Rumata
Зависание системы на очень больших файлах, может, и будет, если не стоит автоопустошитель оперативки. Поскольку речь о тексте, думается, что файлы не настолько большие, чтобы вызвать сбой. У меня таких нет, по крайней мере. Хотя у некоторых админов имеются очень большие логи, но это редкость. И, естественно, нужно чистить (Nothing) переменную с содержимым после каждой записи.

dab00
Так не получится. sw в функции замены будет принимать значение последней строки ( а не каждой в отдельности) обрабатываемого файла. Там же цикл в цикле. Тут регексы нужны.

13

Re: VBS: поиск в строке и удаление этой строки

Спасибо dab00 за коменты, но заменой sw на word в строке  strNewText = Replace(strText, sw, " ") проблему не решишь, т.к. будет удалять только слово word а нам надо всю строку sw. Так что я решил не мучаться а просто копировать в др. файл все строки не содержащие искомое слово word

word = "Source"                 'искомое слово
papka = "c:\temp\"            'папка поиска
otchet = "D:\\test\\otchet.txt"        'файл отчета
i=0




Set objFSO = CreateObject("Scripting.FileSystemObject")
Set file2 = objFSO.OpenTextFile(otchet, 2, True) 


RecursiveFolderScan papka
file2.close

Msgbox "ВСЕ! Обработано "& i &" файлов"




Sub RecursiveFolderScan(FolderPath)
    'Получаем объектную модель текущего каталога
    Set Folder = objFSO.GetFolder(FolderPath)
 
    'Перебираем все файлы в текущем каталоге
    For Each File in Folder.Files
'+++++++++++++++++++++++++++++++++++++++++

Set file1 = objFSO.OpenTextFile(File, 1, False)

Do Until file1.AtEndOfStream
sw = file1.ReadLine()

If InStr(1, sw, word) = 0 Then    'копируем в др. файл все строки не равные этой
                
'file2.WriteLine(file.Name)         
file2.WriteLine(sw)     
                
            End If
        Loop
file1.close
 

objFSO.DeleteFile File, 1    'удаляем исход.файл
'objFSO.MoveFile otchet, File    'почему-то выдает ошибку  переимен-м отчет в исход.файл




i=i+1        'счетчик файлов
'++++++++++++++++++++++++++++++++++++++



    Next
 
    'Перебираем все подкаталоги в каталоге
    For Each SubFolder in Folder.SubFolders
        RecursiveFolderScan(SubFolder.Path)
    Next
End Sub

и кстати файл otchet нельзя размещать в этом же каталоге т.к. скрипт проходит все файлы каталога и будет бесконечно копировать строки из otchet в otchet

14

Re: VBS: поиск в строке и удаление этой строки

и кстати файл otchet нельзя размещать в этом же каталоге т.к. скрипт проходит все файлы каталога и будет бесконечно копировать строки из otchet в otchet

Можно, если сие учесть — проверяя имя файла.

15

Re: VBS: поиск в строке и удаление этой строки

griha09 пишет:

Спасибо dab00 за коменты

Рад, что Вам помогло. Уже очень похоже . Примерно о таком алгоритме чуть выше толковал уважаемый Rumata.