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

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   AutoIt (http://forum.oszone.net/forumdisplay.php?f=103)
-   -   Как в файле изменить определённые строки? (http://forum.oszone.net/showthread.php?t=165197)

NewOLDi 28-01-2010 13:01 1332269

Как в файле изменить определённые строки?
 
Есть файл с большим количеством строк. Нужно найти определённые строки (вхождения фраз) и, при их обнаружении, добавить к началу каждой из них, скажем, символ комментария - ;.

Я знаю как это сделать путём полной перезаписи существующего файла (т.е. загнать инфу из файла в память и все замены провести там, после чего перезаписать существующий файл), но это, имхо, не совсем правильно и память жрёт :)

madmasles 28-01-2010 13:11 1332279

NewOLDi,

_FileWriteToLine() посмотрите в библиотечных функциях, которые
Цитата:

я ооочень люблю...

kaster 28-01-2010 13:22 1332286

Код:

$sFile = @ScriptDir & '\test.txt'; путь до текстового файла, который подлежит обработке - должен существовать
$tmpFile = @ScriptDir & '\test_new.txt'; путь до нового файла, который получится после обработки - если не существует создаться автоматически

$hRead = FileOpen($sFile, 0); открываем первый файл для чтения
$hWrite = FileOpen($tmpFile, 2); открываем/создаем второй файл для записи/перезаписи

$template = 'string must exist in file'; фраза которая должна существовать в строке для начала обработки
$sAdd = ';'; символы которые добавятся перед найденной строкой
While 1
        $sLine = FileReadLine($hRead); считывание строк первого файла одна за другой
        If @error Then ExitLoop; если конец файла выходим из скрипта
        If StringInStr($line, $template) Then; условие нахождения нужной строки
                FileWriteLine($hWrite, $sAdd & $sLine); добавление символов для найденной строки
        Else; условие когда строка не искомая
                FileWriteLine($hWrite, $sLine); просто перезаписываем эту строку как есть
        EndIf; конец условия
WEnd; конец цикла

FileClose($hRead)
FileClose($hWrite); закрываем файлы для соблюдения правил приличия и хороших манер


madmasles 28-01-2010 13:42 1332318

kaster и NewOLDi,

У меня через массив вот так работает:
Код:

#include <file.au3>

$aRecords = ""
_FileReadToArray("my.txt", $aRecords)

For $i = 1 To $aRecords[0]
    If StringInStr($aRecords[$i], "То что ищем") > 0 Then
        _FileWriteToLine("my.txt", $i, StringReplace($aRecords[$i], $aRecords[$i], ";" & _
                $aRecords[$i]), 1)
    EndIf
Next


NewOLDi 28-01-2010 13:55 1332331

kaster, у Вас используются два файла, а нужно всё проворачивать в одном, т.е. и читать и записывать (при необходимости) одновременно.

madmasles, массив-память - одно и тоже (в условиях я указал на это), а нужно напрямую, без загона инфы в память. Представьте, что файл размером в 1 Гб :) И это, любить библиотечные функции - не означает все их знать и уметь пользоваться, любовь здесь с точки зрения разумности использования того, что уже давно придумано и просчитано (типа - зачем изобретать велосипед).

Creat0R 28-01-2010 14:03 1332341

Цитата:

Цитата NewOLDi
это, имхо, не совсем правильно »

Как раз это самый правильный вариант, а память заполняется временно, если переменная массива локальная, то после выхода из функций память высвобождается, а если глобальная, то после использования массива его можно "онулировать":

Код:

$aArray = 0

NewOLDi 28-01-2010 14:30 1332364

Нууу.... нет так нет, бум использовать память и полностью перезаписывать имеющийся файл :)

Creat0R 28-01-2010 14:43 1332375

Цитата:

Цитата NewOLDi
Представьте, что файл размером в 1 Гб »

Но без построчного чтения с начала всё ровно не обойтись:

Код:

$sFile = @DesktopDir & "\File.txt"
$sInStr = "Some Data"

$hFile = FileOpen($sFile, 0)

While 1
    $sLine = FileReadLine($hFile)
    If @error <> 0 Then ExitLoop

    If StringRegExp($sLine, "(?i)^[^;].*" & $sInStr & ".*$") Then
        $iPos = FileGetPos($hFile) - StringLen($sLine) - StringLen(@CRLF)
        FileClose($hFile)

        $hFile = FileOpen($sFile, 1)
        FileSetPos($hFile, $iPos, 0) ;$FILE_BEGIN
        FileWrite($hFile, ";" & $sLine)
        ExitLoop
    EndIf
WEnd

FileClose($hFile)


NewOLDi 28-01-2010 14:49 1332384

Creat0R, нууу - строка не файл, как никак :) Благодарю, вроде как работает.

madmasles 28-01-2010 16:02 1332487

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

NewOLDi 28-01-2010 17:50 1332593

madmasles
Самый быстрый и лёгкий - загнать всю инфу в память и там с ней работать. Но этот вариант не всегда подходит, если речь идёт о слишком больших объёмах данных.

Медленный и муторный, но эффективный с точки зрения объёма занимаемой памяти - работа с файлом напрямую.

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

Так что, исходить нужно из задач, стоящих перед Вами. Отсюда и будет выбираться оптимальный путь...

Ну как-то так :)

ЗЫ: А извращаться над каждым из вариантов можно сколь угодно много, хотя от перестановки мест слагаемых... ну разве что сокращать код и заниматься оптимизацией.

Creat0R 05-02-2010 00:09 1339318

NewOLDi, Тема решена?


Время: 07:54.

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