Jump to content
Sign in to follow this  
pbecks1963

read text file line by line

Recommended Posts

pbecks1963

Hello Y'all,

I am playing around with autoit and i am trying to figure out how to right a script that will:

1) read a text-file, line by line

2) put the line into a variable

This one is not important right now! -> (manipulate the variable and write it back to the file.)

3) read the next line, etc.. etc..

Can someone point me in the direction of a good example or come up with one?

Thnx!!

ps: in my case the number of lines in the text-file can vary (is unknown)

Edited by pbecks1963

Share this post


Link to post
Share on other sites
darkshark

Code Fixed:

Mode 1:

#include <File.au3>

$file = "c:\yourfile.txt"
FileOpen($file, 0)

For $i = 1 to _FileCountLines($file)
    $line = FileReadLine($file, $i)
msgbox(0,'','the line ' & $i & ' is ' & $line)
Next
FileClose($file)

Mode 2:

#include <file.au3>

$file = FileOpen("yourfile.txt", 0)

While 1
    $line = FileReadLine($file)
    If @error = -1 Then ExitLoop
    MsgBox(0,'',$line)
WEnd
FileClose($file)

Mode 3:

#include <Array.au3>
#include <File.au3>

Local $aInput
$file = "yourfile.txt"

_FileReadToArray($file, $aInput)
For $i = 1 to UBound($aInput) -1
    MsgBox (0,'',$aInput[$i])
Next

all tested!

Edited by darkshark

Share this post


Link to post
Share on other sites
pbecks1963

Hello DarkShark,

I am trying this:

#include <File.au3>

$file = fileopen("c:\yourfile.txt", 0)

For $i = 1 to _FileCountLines($file)

$line = FileReadLine($file, $i)

msgbox(0,"","the line " & $i & " is " & $line)

Next

FileClose($file)

But it doesn't do a thing... (c:\yourfile.txt exists and has 8 lines)

Edited by pbecks1963

Share this post


Link to post
Share on other sites
nf67

Hello DarkShark,

I am trying this:

#include <File.au3>

$file = fileopen("c:\yourfile.txt", 0)

For $i = 1 to _FileCountLines($file)

$line = FileReadLine($file, $i)

msgbox(0,"","the line " & $i & " is " & $line)

Next

FileClose($file)

But it doesn't do a thing... (c:\yourfile.txt exists and has 8 lines)

I think it might be that $file = fileopen(path) and is used with another command afterwards, perhaps you should remove fileopen? I'm not sure and haven't tested it myself.

Share this post


Link to post
Share on other sites
darkshark

i've fixed the code

:mellow:

sorry for my error ><

Share this post


Link to post
Share on other sites
nf67

Documented code:

#include <File.au3>

$OldFilePath = @ScriptDir & "\OldFile.txt" ;Old file path defined
$NewFilePath = @ScriptDir & "\NewFile.txt" ;New file path defined

Manipulate() ;Use the function "Manipulate"

Func Manipulate() ;Start of the function "Manipulate" no parameters so ()
    For $Line = 1 to _FileCountLines($OldFilePath) ;For the variable $Line being 1 up to and including the number of lines in the old file
            $OldLine = FileReadLine($OldFilePath, $Line) ;Read the line
            $NewLine = $OldLine & " and something else." ;Edit the line
            FileWriteLine($NewFilePath, $NewLine) ;Write the new line to a file
    Next ;Then... (end of For loop)
    MsgBox(0,"Done","The manipulated lines were written to the following file: " & $NewFilePath) ;Announce that it's done.
EndFunc ;End of the "Manipulate function"

:-)

Edited by nf67
  • Like 1

Share this post


Link to post
Share on other sites
MHz

There are some issues with some of the example code being displayed. I will list them as suggestions below.

  • If you use FileOpen(), then you need to use the file handle returned from FileOpen. Close the file handle with FileClose() when done.
  • The 2nd parameter of FileReadLine() is best not used unless you want to read a certain line. If you do use the 2nd parameter in a loop with using a variable for counting, then AutoIt will read from line 1 -> line 2, then line 1 -> line 2 -> line 3, then line 1 -> line 2 -> line 3 -> line 4 etc. It is better to omit the 2nd parameter and let AutoIt handle the count internally as the file will be read one line after the other.
  • _FileCountLines() uses FileOpen() on the passed parameter so use a filename as the parameter to pass to _FileCountLines()

:mellow:

Edited by MHz

Share this post


Link to post
Share on other sites
pbecks1963

Thanks you all, but how would this change the last script mentioned?

ps: I changed the script a bit to remove unwanted symbols (CR or LF)

*********************************************************************************

#include <File.au3>

RunWait( @comspec & " /c del /q " & @ScriptDir & "\NewFile.txt","",@SW_HIDE)

$OldFilePath = @ScriptDir & "\OldFile.txt" ;Old file path defined

$NewFilePath = @ScriptDir & "\NewFile.txt" ;New file path defined

Manipulate() ;Use the function "Manipulate"

Func Manipulate() ;Start of the function "Manipulate" no parameters so ()

For $Line = 1 to _FileCountLines($OldFilePath) ;For the variable $Line being 1 up to and including the number of lines in the old file

$OldLine = FileReadLine($OldFilePath, $Line) ;Read the line

$NewLine = StringReplace($OldLine, "1", "number 1 is replaced")

$NewLine = StringReplace($NewLine, "" , "")

FileWriteLine($NewFilePath, $NewLine) ;Write the new line to a file

Next ;Then... (end of For loop)

;MsgBox(0,"Done","The manipulated lines were written to the following file: " & $NewFilePath) ;Announce that it's done.

;MsgBox(0,"Message","Number of lines in " & $OldFilePath & " :" & $Line - 1)

EndFunc ;End of the "Manipulate function"

FileCLose($NewFilePath)

FileCLose($OldFilePath)

***********************************************************************************

The "" symbol (CR? or LF? not sure) looks different in the Notepad on my pc (more a "square" symbol)

Any suggestions?

Edited by pbecks1963

Share this post


Link to post
Share on other sites
MHz

Thanks you all, but how would this change the last script mentioned?

The example mentioned uses the 2nd parameter in FileRedLine() for no good reason. As I mentioned previous, it is not good and it will get slower and slower as each line is read as AutoIt needs to start from the 1st line again to count to the given line.

The help file has some good examples so I am not sure why you cannot learn from there, but I will give you an example that reflects your request at the 1st post. :mellow:

; filename to read
$file_to_read = "file_to_read.txt"
; open file to read and store the handle
$handle_read = FileOpen($file_to_read, 0)
; check the handle is valid
If $handle_read = -1 Then
    ; show warning and exit with code 1
    MsgBox(0, @ScriptName, 'failed to open handle to read the file')
    Exit 1
EndIf

; filename to write
$file_to_write = "file_to_write.txt"
; open file to read and store the handle
$handle_write = FileOpen($file_to_write, 2); erase mode
; check the handle is valid
If $handle_write = -1 Then
    ; close read handle here as write handle is invalid
    FileClose($handle_read)
    ; show warning and exit with code 2
    MsgBox(0, @ScriptName, 'failed to open handle to read the file')
    Exit 2
EndIf

; loop through each line of the file
While 1
    ; read each line from a file
    $line_read = FileReadLine($handle_read)
    ; exit the loop if end of file
    If @error Then ExitLoop
    ; show the line read (just for testing)
    MsgBox(0, 'Line read', $line_read)
    ; write each line to a file
    FileWriteLine($handle_write, $line_read)
WEnd

; close the file handle for read
FileClose($handle_read)
; close the file handle for write
FileClose($handle_write)

Almost more comments then code so hopefully it is understandable to learn from.

Share this post


Link to post
Share on other sites
pbecks1963

Thnx! I will learn from your code!

Share this post


Link to post
Share on other sites
gawron25

The example mentioned uses the 2nd parameter in FileRedLine() for no good reason. As I mentioned previous, it is not good and it will get slower and slower as each line is read as AutoIt needs to start from the 1st line again to count to the given line.

The help file has some good examples so I am not sure why you cannot learn from there, but I will give you an example that reflects your request at the 1st post. :mellow:

 

; filename to read
$file_to_read = "file_to_read.txt"
; open file to read and store the handle
$handle_read = FileOpen($file_to_read, 0)
; check the handle is valid
If $handle_read = -1 Then
    ; show warning and exit with code 1
    MsgBox(0, @ScriptName, 'failed to open handle to read the file')
    Exit 1
EndIf

; filename to write
$file_to_write = "file_to_write.txt"
; open file to read and store the handle
$handle_write = FileOpen($file_to_write, 2); erase mode
; check the handle is valid
If $handle_write = -1 Then
    ; close read handle here as write handle is invalid
    FileClose($handle_read)
    ; show warning and exit with code 2
    MsgBox(0, @ScriptName, 'failed to open handle to read the file')
    Exit 2
EndIf

; loop through each line of the file
While 1
    ; read each line from a file
    $line_read = FileReadLine($handle_read)
    ; exit the loop if end of file
    If @error Then ExitLoop
    ; show the line read (just for testing)
    MsgBox(0, 'Line read', $line_read)
    ; write each line to a file
    FileWriteLine($handle_write, $line_read)
WEnd

; close the file handle for read
FileClose($handle_read)
; close the file handle for write
FileClose($handle_write)
Almost more comments then code so hopefully it is understandable to learn from.

 

How can you use this script to paste line by line to another application, such as Notepad, where you paste one line of presses enter, and then moves to the next until the there will be no text for pasting.

sorry for bumping old thread.

Share this post


Link to post
Share on other sites
padmanabangs

Hi all,

   I am new to Autoit, so kindly bear with me, if my doubts are silly..

  I am able to read the contents of my file, and the output of the file is something like,

Example :-   Line 1 =  375678         23433

  Now I want to write the first part of my Line 1 (37568) in a ini file, under seperate key and second part of Line 1 under a seperate key in the same ini file.

 Expected o/p :

 ===========

[TestData]

firstpart       = 375678 

secondpart = 23433

thirdpart = 37567823433

 

Thanks in Advance,

Padmanaban G S

Share this post


Link to post
Share on other sites
MHz

Hi padmanabangs. Welcome to AutoIt.

Some changes to the code I posted prior and that will hopefully do it. Your info is a little vague so hopefully I have guessed correct.

; filename to read
$file_to_read = "file_to_read.txt"
; open file to read and store the handle
$handle_read = FileOpen($file_to_read, 0)
; check the handle is valid
If $handle_read = -1 Then
    ; show warning and exit with code 1
    MsgBox(0, @ScriptName, 'failed to open handle to read the file')
    Exit 1
EndIf

; loop through each line of the file
While 1
    ; read each line from a file
    $line_read = FileReadLine($handle_read)
    ; exit the loop if end of file
    If @error Then ExitLoop
    ; get 2 parts of the line separated by whitespace
    $line_array = StringRegExp($line_read, '(.+?)\s+(.+)', 3)
    ; check that 2 elements exist in the array
    If UBound($line_array) = 2 Then
        ; write to the ini file
        IniWrite('test.ini', 'TestData', 'firstpart', $line_array[0])
        IniWrite('test.ini', 'TestData', 'secondpart', $line_array[1])
        IniWrite('test.ini', 'TestData', 'thirdpart', $line_array[0] & $line_array[1])
    EndIf
WEnd

; close the file handle for read
FileClose($handle_read)

Outputs:

[TestData]
firstpart=375678
secondpart=23433
thirdpart=37567823433

Seems to match your expectation?

Share this post


Link to post
Share on other sites
padmanabangs

Hi Mhz,
 
    First of All, thanks for your valuable response.. You were absolutely right on understanding my query :thumbsup:
 
   And the code you provided was very much useful to me. Now I am able to save the values in .ini file and achieve my expected o/p.
 
  I dont want to stop with only using this code, but I would like to clarify a small doubt so that I can understand better.
 

 ==> How did you get the two parts of the line seperate by white space?

   $line_array = StringRegExp($line_read, '(.+?)s+(.+)', 3)
 

    I went thorught the help document for "StringRegExp" , but I couldnt understand how the above line works.

 

Thanks & Regards,

Padmanaban G S

Share this post


Link to post
Share on other sites
Melba23

padmanabangs,

RegExes are too big a subject to cover in a forum thread - they are a whole new language to learn. :o

In this case the pattern decodes as follows:

(.+?)  - Capture a group containing all characters (there may be none)...
\s+    - until we reach one or more spaces (which we ignore)...
(.+)   - and then capture all the other characters until the end

3      - Return the captured groups as an array
I hope that helps. :)

I recommend this site to start learning about RegExes - good luck. ;)

M23

  • Like 2

Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites
MHz

==> How did you get the two parts of the line seperate by white space?

   $line_array = StringRegExp($line_read, '(.+?)s+(.+)', 3)

 

OK, lets break the pattern down.

(.+?) is the first capture group that gets all characters up to the next match.

The dot is any character. The + is continue with next character possessively. The ? tells it to be lazy so it will not go beyond what is enough.

So with "375678         23433", the dot matches 3, then 7, then 5, then 6, then 7, then 8, then a space is seen so the capture stops. The 1st capture is "375678".

s+ is to match all whitespace up to the next match.

" " is matched, next " ", ... until the 2 is seen, thus the matching stops. The spaces cause the regex is progress yet not capture those spaces as being "         ".

(.+) is the 2nd and last capture group and will get all characters up to the end of the string.

The dot is any character. The + is continue with next character possessively. No ? is used so it is relentless to match, no looking back, always wanting to go forward. The 2nd capture is "23433".

The 2 capture create the array as

$line_array[0] = "375678"

$line_array[1] = "23433"

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  

×