Sign in to follow this  
Followers 0
BlueScreen

_ReplaceStringInFile

21 posts in this topic

Hi all,

I was wondering if there is a way using _ReplaceStringInFile in order to delete the line itself and not only it's "content"

Here is the content of my file:

-----------------------------------

This is line number 1

This is line number 2

This is line number 3

Here is what I want:

-------------------------

This is line number 1

This is line number 3

Thanks,

Share this post


Link to post
Share on other sites



you could use StringReplace() to do it, but you would have to write it to another file, you couldn't alter the actual file itself this way...

I imagine what _ReplaceStringInFile() does is open the file you want to read / Read the file to an array, find the string you want to replace, exclude or add it to the new given output, create another file, re-write all the lines to that 'hold file', delete the file you actually had / and filemove() the new made file to the same directory with the same name.

At least that's how I would write it anyway...


[center]Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.[/center]

Share this post


Link to post
Share on other sites

Something like this type of thing?

$File = Fileopen ("file.txt", 0)
$FileOut = FileOpen ("file.tmp",1)
While 1
    $line = FileReadLine($file)
        If @error = -1 Then ExitLoop
        If not StringinStr ($Line, "Text of line you don't want") > 0 then FileWriteLine ($FileOut, $Line)
    Wend
    
FileClose ($File)
FileClose ($FileOut)

FileDelete ( "file.txt" )
FileMove ("File.tmp", "File.txt")

Share this post


Link to post
Share on other sites

Something like this type of thing?

$File = Fileopen ("file.txt", 0)
$FileOut = FileOpen ("file.tmp",1)
While 1
    $line = FileReadLine($file)
        If @error = -1 Then ExitLoop
        If not StringinStr ($Line, "Text of line you don't want") > 0 then FileWriteLine ($FileOut, $Line)
    Wend
    
FileClose ($File)
FileClose ($FileOut)

FileDelete ( "file.txt" )
FileMove ("File.tmp", "File.txt")
:lmao: ... close to what 'I' had in mind, hope it's what he needs!! Nice Job.

[center]Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.[/center]

Share this post


Link to post
Share on other sites

Thanks, SmOke_N and ChirsL!

This is it exactelly!!!

Cheers!

Share this post


Link to post
Share on other sites

Why?? I always see the word thanks ChrisL SmOke N (whatever)


New Owner of this AU account

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

As I said, it works fine, but since I need to parse a file containing 10000 lines (and I need to do it 3 times), it takes quite a while...

Is there another solution? For example if I don't use FilereadLine, but do the compare with an array (_FileReadToarray), would it be faster?

Edited by BlueScreen

Share this post


Link to post
Share on other sites

Why?? I always see the word thanks ChrisL SmOke N (whatever)

UMMMMMMMMMMM maybe cuz they like to help people? mulawin DONT EVEN START POSTING please youll just confused yourself and everyone as well just go have fun with my recruiter..........................................

Share this post


Link to post
Share on other sites

As I said, it works fine, but since I need to parse a file containing 10000 lines (and I need to do it 3 times), it takes quite a while...

Is there another solution? For example if I don't use FilereadLine, but do the compare with an array (_FileReadToarray), would it be faster?

Why do it 3 times, just put the (3) strings you dont want into your if statement and just do it once

#include <Array.au3>
#include <file.au3>

Dim $aInfile
Dim $aOutfile = _ArrayCreate("0")

If Not _FileReadToArray("File.txt",$aInfile) Then
   MsgBox(4096,"Error", " Error reading file to Array    error:" & @error)
   Exit
EndIf


For $x = 1 to $aInfile[0]
If StringinStr ($aInfile[$x], "Text 1 to erase") = 0 and StringinStr ($aInfile[$x], "text 2 to erase") = 0 and StringinStr ($aInfile[$x], "Text 3 to erase") = 0  then 
    _ArrayAdd ( $aOutfile, $aInfile[$x] )
    $aOutfile[0] += 1
    Endif
Next

_FileWriteFromArray("File.tmp",$aOutfile,1)

FileDelete ( "file.txt" )
FileMove ("File.tmp", "File.txt")

Share this post


Link to post
Share on other sites

Why do it 3 times, just put the (3) strings you dont want into your if statement and just do it once

#include <Array.au3>
#include <file.au3>

Dim $aInfile
Dim $aOutfile = _ArrayCreate("0")

If Not _FileReadToArray("File.txt",$aInfile) Then
   MsgBox(4096,"Error", " Error reading file to Array    error:" & @error)
   Exit
EndIf
For $x = 1 to $aInfile[0]
If StringinStr ($aInfile[$x], "Text 1 to erase") = 0 and StringinStr ($aInfile[$x], "text 2 to erase") = 0 and StringinStr ($aInfile[$x], "Text 3 to erase") = 0  then 
    _ArrayAdd ( $aOutfile, $aInfile[$x] )
    $aOutfile[0] += 1
    Endif
Next

_FileWriteFromArray("File.tmp",$aOutfile,1)

FileDelete ( "file.txt" )
FileMove ("File.tmp", "File.txt")
Nice work chris... but if you don't mind me asking, why go for the _ArrayAdd() rather than $var = $var & $aInfile[$x] & @LF ?

But definately takes care of multiple non-essential loops.


[center]Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.[/center]

Share this post


Link to post
Share on other sites

#11 ·  Posted (edited)

Nice work chris... but if you don't mind me asking, why go for the _ArrayAdd() rather than $var = $var & $aInfile[$x] & @LF ?

But definately takes care of multiple non-essential loops.

To be honest I don't know, that was the only way I knew.. would your way be better?

Edit* I see what you mean now, I just chucked it into a second array because thats what (he) wanted to do.

Your saying just create a variable and write it.

I suppose if its in a second array then if (he) needed to search again it would be quicker.

Edited by ChrisL

Share this post


Link to post
Share on other sites

#12 ·  Posted (edited)

To be honest I don't know, that was the only way I knew.. would your way be better?

Edit* I see what you mean now, I just chucked it into a second array because thats what (he) wanted to do.

Your saying just create a variable and write it.

I suppose if its in a second array then if (he) needed to search again it would be quicker.

You could create the 2nd array by:

$var = $var & $line[$elementnumber] & Chr(01)

Next

$NewArray = StringSplit(StringTrimRight($var, 1), Chr(01))

Return $NewArray

... A single line your way with _ArrayAdd() but if you look at the UDF it's not a 'Single' line so in some situations, the above may be all you need, and may reproduce 'faster' and safer results because you can see exactly what it is doing.

But personally, I don't see 1 thing wrong with your script at all. I think it was a very valid post!!... Good Job!

Edit: Forgot a bracket!! :lmao:

Edited by SmOke_N

[center]Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.[/center]

Share this post


Link to post
Share on other sites

#14 ·  Posted (edited)

OK this is probably better.. because using the StringInStr you could have a string which contains what you are looking for but is infact a longer string and I used Sm0ke_N's way of splitting the string, oh and this deletes the original file which you may not want, I never pointed this out before.

#include <Array.au3>
#include <file.au3>

Dim $aInfile
Dim $aOutfile
$Var =""

If Not _FileReadToArray("packfile.ini",$aInfile) Then
   MsgBox(4096,"Error", " Error reading log to Array     error:" & @error)
   Exit
EndIf


For $x = 1 to $aInfile[0]
    if  $aInfile[$x] <> "[LayoutList]" and  $aInfile[$x] <> "layout0=A5-(5X3.5)X2" and $aInfile[$x] <> "layout1=A5-(6X4)X1" then $var = $var & $aInfile[$x] & Chr(01)
Next


$aOutFile = StringSplit(StringTrimRight($var, 1), Chr(01))

_FileWriteFromArray("File.tmp",$aOutfile,1)

FileDelete ( "file.txt" )
FileMove ("File.tmp", "File.txt")
Edited by ChrisL

Share this post


Link to post
Share on other sites

#15 ·  Posted (edited)

Hi Guys,

First, thanks for your help.

I have written a function which receives as 2 parameters 2 files: RemoveData ($SRCfile, $DataFile<from an array>) and remove from the Source file the Data which exists on the DataFile.

All works fine, but very low (5 minutes). Is my algorithm not efficient enough? :lmao:

For $w=1 to $NumOfDataFiles
     RemoveDatafromSrc ($SRCfile,$Data[$w-1][0])
Next

Here is what I did inside the function:

1) Read the Data file into an array using _FileReadToArray

2) Read the SRC file into another array using _ FileReadToArray

3) Openning a temp file

4) Running in a Loop (as many lines there is in the SRC file) and checking (for each SRC line) using StringInStr(in a while) if the line in the SRC file, contains strings from the Data file.

5) If all the lines in the Data file was read and there is no match, than the line can be written in a temp file.

6) All this is running till there is no more lines in the SRC file.

7) Closing the temp file, deleting the SRC, Moving the Temp file to SRC

8) Arriving here, there are no Strings from the DATA file into the SRC file. Continuing with the next Data file

Now, my SRC file contains around 8000 lines. I have also 6 Data file of 30 lines each. So, in order to go over all the lines (around 1440000), it takes about 5 minutes

Is there a way to do it better? Here is my code:

Dim $Temp[1]
Dim $SrcValue
Dim $DataValue
Global $LineInData=1
Global $TempID=1
#include <file.au3>

Func RemoveDatafromSrc ($SrcFile,$DataFile)
    
    If Not _FileReadToArray($DataFile,$DataValue) Then Exit
        
    If Not _FileReadToArray($SrcFile,$SrcValue) Then Exit
        
    For $e=1 to $DataValue[0]
        $DataValue[$e]=StringLeft($DataValue[$e],4); I need only the 4 left chars
    Next
    
    $TmpFile = FileOpen ("temp.tmp",2)
    
    For $LineInSrc=1 to $SrcValue[0]; Lines in SRC
        While $LineInData <= $DataValue[0]; for each Src line, need to check all DATA line
            If StringinStr ($SrcValue[$LineInSrc], $DataValue[$LineInData] & ":") <> 0 then
    ;Data line found
                ExitLoop
            EndIf
            If $LineInData=$DataValue[0] Then
                FileWriteLine($TmpFile,$SrcValue[$LineInSrc] & @LF)
                $LineInData=1
                ExitLoop
            Else
                $LineInData=$LineInData+1
            EndIf
        WEnd
    Next
    FileClose ($TmpFile)
    FileDelete ($SrcFile)
    FileMove ("temp.tmp", $SrcFile,1)
EndFunc
Edited by BlueScreen

Share this post


Link to post
Share on other sites

Hi,

If you want speed, use DOS.

If you follow the link in my signature to "_DOSDeleteFoundLineEx1.au3", via DOSCOMS.au3 or bookmarks, you will find a modified DOS command

Has been known to search for 50 exclusions [put them in 1 string from your data files] in 500,000 lines [80Mb] in 40 secs

Best, Randall

Share this post


Link to post
Share on other sites

The place where you are going to reduce speed is the reading and writing of the arrays from the hard drive.

You need to look at reading the Main array - Array 1

Do your string left but create that into a second array Array 2

read your data file into Array 3

Loop through array 3 searching array 2 if you need to add a value, dont write it to a text file but write it back to array 1, then when you get to the next data file, repeat the process from create Array 2 from the newly modified array 1, once you have done all of your data files then write array 1 to a txt file.

This would mean only one read of the main (large) file and one write of the main file

Share this post


Link to post
Share on other sites

Why?? I always see the word thanks ChrisL SmOke N (whatever)

because their helpful posts are appreciated, very much unlike the posts i've seen from you tonight.

1100111 00001011101111 00011101101111 00010111100100 00001111110100 00110111110010 00101101111001 0011100i didn't make up this form of encryption, but i like it.credit to the lvl 6 challenge on arcanum.co.nz

Share this post


Link to post
Share on other sites

because their helpful posts are appreciated, very much unlike the posts i've seen from you tonight.

Ha... He was thanking ChrisL (Well Deserved) and basically calling me an Asshole!! ;) (:lmao: Also may be well deserved... but only from 'Peers'!! which from his manerisms, he may be.... in another 10 or 15 yrs! **Gotta read between the lines on that one**)


[center]Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.[/center]

Share this post


Link to post
Share on other sites

Do your string left but create that into a second array Array 2

I don't get it... :lmao:

Loop through array 3 searching array 2 if you need to add a value, dont write it to a text file but write it back to array 1, then when you get to the next data file, repeat the process from create Array 2 from the newly modified array 1, once you have done all of your data files then write array 1 to a txt file.

I don't get it either. Sorry, I am kinda slow today. ;)

Can u please put your suggestion into the code I have posed? o:)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0