Jump to content
DjDiabolik

Variable for each line in a txt file... it's possible ?

Recommended Posts

Hi boys&Friends... i return here for try to found some help..... i'm stay to create a script based download list using curl.

I'm blocked from hours in this parts of code.... i can post this part:

Func ReadFile()
    For $Num = 1 to 100 step 1
        Global $Down[$Num] = FileReadLine($File, $Num)
        Global $DownZip[$Num] = $Down[$Num] & ".zip"
        ;MsgBox($MB_SYSTEMMODAL, "TEST", $Down & ".zip")
    Next
    MsgBox($MB_SYSTEMMODAL, "TEST", $DownZip[50])
    EndFunc   ;==>ReadFile

The $File it's a text file present on same path of .au3. That's it's contain a list files for each line.... somethings like:

aaaa
bbbb
cccc
dddd

etc etc. This files contain much more 100 line but i need to read only the first 100 line and it's my desire to obtain every line a variable.

After that i need to obtain a variable like $Down50 contain the line 50 of the txt file (plus i have add the extension .zip) for parse download.

 

I have tryes some variable.... $Down($Num), $Down[$Num], and many others and apparently not works.....

 

How i can do this ?

 

Instead to create 100 different variable.... i thinks i can read one line and download zip files on another func. After download complete step back to loop and next line etc etc..... you thinks it's a good idea ?

Edited by DjDiabolik

Share this post


Link to post
Share on other sites

Declare you arrays outside loop like this :

#include <Constants.au3>

Global $Down[100],$DownZip[100]
ReadFile ("Test.txt")
MsgBox($MB_SYSTEMMODAL, "TEST", $DownZip[50])

Func ReadFile($File)
  For $Num = 1 To 100 Step 1
    $Down[$Num-1] = FileReadLine($File, $Num)
    $DownZip[$Num-1] = $Down[$Num] & ".zip"
  Next
EndFunc   ;==>ReadFile

 

Share this post


Link to post
Share on other sites
24 minutes ago, Nine said:

Declare you arrays outside loop like this :

#include <Constants.au3>

Global $Down[100],$DownZip[100]
ReadFile ("Test.txt")
MsgBox($MB_SYSTEMMODAL, "TEST", $DownZip[50])

Func ReadFile($File)
  For $Num = 1 To 100 Step 1
    $Down[$Num-1] = FileReadLine($File, $Num)
    $DownZip[$Num-1] = $Down[$Num] & ".zip"
  Next
EndFunc   ;==>ReadFile

 

Oh.. interesting... great suggestion :)

For moment i stay to try to download the zip every read line..... in this mode:

Func ReadFile()
    For $Num = 1 to 5 step 1
        Global $Down = FileReadLine($File, $Num)
        Global $DownZip = $Down & ".zip"
        Download()
    Next
EndFunc   ;==>ReadFile

After the function download it's complete it's step back read next line and function Download as reach again...

It's a valid alternative instead to create 100 variable for every line..... at the end i need only to download the first 100 zip in the txt files... similar result. It's problably useless to create 100 different variables.

Read line 1 - > Download -> Read Line 2 -> Download. It's also a valid alternative for my reach whit this script :)

 

*EDIT 1 to 5... 5 it's for do test....

 

*Edit 2parts*

I'm right now again block at download section:

Func Download()
    Global $LinkFile = $LinkBase & $Downzip & '"'
    Global $LinkFinale = $CurlCmd & " --output .\Download\" & $DownZip & $LinkFile
    MsgBox($MB_OKCANCEL, "TEST", $LinkFinale)
    If $IDCANCEL = 2 then
        MsgBox($MB_SYSTEMMODAL,"","Ciao Ciao... Bambina")
    EndIf
    MsgBox($MB_SYSTEMMODAL,"","Start Download")
    ;Run ($LinkFinale)
EndFunc

I need to skip the download if i click cancel on msgbox..... there's no GOTO or similar on autoit and i have try to use func and it's not help.... how i can do this ?

Edited by DjDiabolik

Share this post


Link to post
Share on other sites

Just use Return, also don't declare global variables within functions, something like (untested):

Global $LinkBase = "https://www.example.com/downloads/"

Func ReadFile()
    For $Num = 1 to 5 step 1
        Download(FileReadLine($File, $Num) & ".zip")
    Next
EndFunc   ;==>ReadFile

Func Download($Downzip)
    Local $LinkFile = $LinkBase & $Downzip & '"'
    Local $LinkFinale = $CurlCmd & " --output .\Download\" & $DownZip & $LinkFile
    Local $MsgBox = MsgBox($MB_OKCANCEL, "TEST", $LinkFinale)
    If $MsgBox = 2 then
        MsgBox(4096,"","Ciao Ciao... Bambina")
        Return
    EndIf
    MsgBox(4096,"","Start Download")
    ;Run ($LinkFinale)
EndFunc

 

Edited by Subz

Share this post


Link to post
Share on other sites
1 minute ago, Subz said:

Just use Return, also don't declare global variables within functions, something like (untested):

Global $LinkBase = "https://www.example.com/downloads/"

Func ReadFile()
    For $Num = 1 to 5 step 1
        Download(FileReadLine($File, $Num) & ".zip")
    Next
EndFunc   ;==>ReadFile

Func Download($Downzip)
    Local $LinkFile = $LinkBase & $Downzip & '"'
    Local $LinkFinale = $CurlCmd & " --output .\Download\" & $DownZip & $LinkFile
    MsgBox($MB_OKCANCEL, "TEST", $LinkFinale)
    If $IDCANCEL = 2 then
        MsgBox(4096,"","Ciao Ciao... Bambina")
        Return
    EndIf
    MsgBox(4096,"","Start Download")
    ;Run ($LinkFinale)
EndFunc

 

I have tryed somethigs similar.... but apparently there's can be obtain a working.

Also some test i obtain this:

Func Download()
    Global $LinkFile = $LinkBase & $Downzip & '"'
    Global $LinkFinale = $CurlCmd & " --output .\Download\" & $DownZip & $LinkFile
    Global $Answer1 = MsgBox($MB_OKCANCEL, "TEST", $LinkFinale)
    If $Answer1 = 1 Then
        MsgBox($MB_SYSTEMMODAL,"","Start Download")
    EndIf
    If $Answer1 = 2 Then
        MsgBox($MB_SYSTEMMODAL,"","Ciao Ciao... Bambina")
    EndIf
EndFunc

I have set a variable for MsgBox..... after this the check of this variable working good.

 

I thinks i can open directly a new thread whit all my script test............ i thinks i can post all my script to obtain a much better help from this forum.. right ?

Share this post


Link to post
Share on other sites

Updated my code above, I missed that you hadn't assigned the variable, you can use If/ElseIf or Switch to detect the answer but the updated post should be sufficient.

 

Share this post


Link to post
Share on other sites
2 minutes ago, junkew said:

https://www.autoitscript.com/autoit3/docs/libfunctions/_FileReadToArray.htm probably still is fastest and you can directly

reference $file[50]

You speak about read line by line and store every line to a single variable ?

At right now i'm stay to use an alternative ways.

1) A loop for line number.

2) Read Line Number 1 on txt

3) Download the .zip

4) Next on loop

 

I have done so other things in this my script.... if i need much help i thinks it's can be better to open a different thread how i can post all my script.....

Share this post


Link to post
Share on other sites
On 12/2/2019 at 4:11 PM, Subz said:

Just use Return, also don't declare global variables within functions, something like (untested):

Global $LinkBase = "https://www.example.com/downloads/"

Func ReadFile()
    For $Num = 1 to 5 step 1
        Download(FileReadLine($File, $Num) & ".zip")
    Next
EndFunc   ;==>ReadFile

Func Download($Downzip)
    Local $LinkFile = $LinkBase & $Downzip & '"'
    Local $LinkFinale = $CurlCmd & " --output .\Download\" & $DownZip & $LinkFile
    Local $MsgBox = MsgBox($MB_OKCANCEL, "TEST", $LinkFinale)
    If $MsgBox = 2 then
        MsgBox(4096,"","Ciao Ciao... Bambina")
        Return
    EndIf
    MsgBox(4096,"","Start Download")
    ;Run ($LinkFinale)
EndFunc

 

@Subz Hi friends..... after 24 hours i have completed one version of my desire script.

For the moment the solution about read one line and immediatelly after download it's a good idea but right now i'm try to write a script 2.0 will output a list of zip files and a confirmation to start download or not.

For obtain this i thinks i need to store every line in a variable and whit a second loop try to found a way to list all variable zip files........

Using the MsgBox it's not a great idea...... how i can appears a list like code or text list ?

 

I have also tryed to use this your suggestion but i thinks there's an errors..... It's say Down(FileReadLine) Error:Unknow Function Name problably because it's need to set a variable here. I have try $Down(FileReadLine($File,$Num) and it's not works.

After that i have also tryed to output $Down50 and it's also no works....

 

*EDIT*

Whit this:

Func ReadFile()
    For $Num = 1 To 5 Step 1
        $Down(FileReadLine($File,$Num)
        $Down = Down & '.zip'
    Next
EndFunc

AutoIT report error: Variable cannot be accessed in this manner.

 

 

Otherwise it's not works..... or I can't write it myself... this is full script 2.0 :) :

#cs ----------------------------------------------------------------------------
     AutoIt Version: 3.3.14.5
 Author:         myName
     Script Function:
    Template AutoIt script.
    #ce ----------------------------------------------------------------------------
    ; Script Start - Add your code below here
#include <FileConstants.au3>
#include <MsgBoxConstants.au3>
#include <WinAPIFiles.au3>
#include <MsgBoxConstants.au3>
    Global $User = "User"
Global $Pass = "Pass"
Global $UserAgent = '"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:70.0) Gecko/20100101 Firefox/70.0"'
Global $LinkBase = '"https://filelist.info/downloads/'
Global $CurlOpz = '-w "%{http_code}\n" --show-error -C - --retry 3 --fail-early --fail --connect-timeout 90 --user ' & $User & ':' & $Pass & ' --user-agent ' & $UserAgent
;InputBox('Variabile', '$CurlOpz', $CurlOpz, '', 1500) ;<- Controllo Variabile
Global $File, $Num, $Down
Local $CheckFileExist
    SetFile()
ReadFile()
ListFile()
    Func SetFile()
    $File = ('list.txt') ;<-Skip InputBox Seguente
    ;$File = InputBox("Richiesta", "Inserisci Nome TXT") ;, "", "", -1, -1, 0, 0)
    If @error = 1 Then
        Exit
    EndIf
    $CheckFileExist = FileExists('.\' & $File)
        If $CheckFileExist Then
            
        Else
            MsgBox($MB_SYSTEMMODAL, "", "File non esistente.... riprova!")
            SetFile()
        EndIf
    If $File = '' Then
    SetFile()
    EndIf
EndFunc
    Func ReadFile()
    For $Num = 1 To 5 Step 1
        $Down = (FileReadLine($File,$Num) & '.zip')
        ;$Down = Down & '.zip'
    Next
EndFunc
    Func ListFile()
    InputBox('Variabile', '$Down', $Down, '', 1500) ;<- Controllo Variabile
EndFunc

there are several variables useful for future purposes like "LinkBase" and "CurlOpz" (need in future to download the zip files. For the moment for the moment i'm trying to bring up the listing on the screen........ but i can't :(

 

This upper code it's works.... but i can't obtain $Down1, $Down2 etc etc. If i check value of $Down4 i obtain it's not declare. If i check the value of $Down i obtain correctly only the five line of list.txt.

 

 

*EDIT After some TEST*

This Part of upper script i write after some test.............. it's half works. Not how i want:

Func ReadFile()
    $Down = FileReadToArray($File)
    $Num = @extended
    ;$Num = 5
    For $i = 0 to $Num - 1
        If $Down[$i] = '.zip' then
            Exit
        EndIf
        $Down[$i] = $Down[$i] & '.zip'
        ;MsgBox($MB_SYSTEMMODAL, "", $Down[$i])
    next
EndFunc
    Func ListFile()
    for $i = 0 to 5 - 1
            If $Down[$i] = '.zip' then
                Exit
            EndIf
        InputBox('Variabile', '$Down', $Down[$i], '', 1500) ;<- Controllo Variabile
    next
EndFunc

The "ReadFile()" apparently works correctly (picked from help) and read all line and create for every line one variable.

It's ok... but if i have a large file txt ?? How it's appen ??

 

On the "ListFile()" there's need some check or some help........ remember ?? I need to read the first 100 line or txt..... i don't have idea how i can do right now.

Some Suggestion ?

also if the file contains less than 100 lines i need to stop.... from this i have tryed 0 to 5 but i obtain an errors says "Incorrect Number or Dimension Range" when i tryed whit only 4 line .txt as source.

Damn......

Edited by DjDiabolik

Share this post


Link to post
Share on other sites

Just use the file read to array function. Your files have to be real big before it becomes an issue. Just test it with your largest file.

Alternative just read first 32000 bytes and use regular expression to get your fifth line

Share this post


Link to post
Share on other sites
15 minutes ago, junkew said:

Just use the file read to array function. Your files have to be real big before it becomes an issue. Just test it with your largest file.

Alternative just read first 32000 bytes and use regular expression to get your fifth line

You suggest to use FileRead instead FileReadToArray ?

Currently my txt files contain about 700 lines but sometimes can contain so much line.......

 

I don't understand because there's can be usable somethings like this:

Func ReadFile()
      For $i = 1 To 100 Step 1
        $Down[$i] = FileReadLine($File, $i)
        MsgBox($MB_SYSTEMMODAL, "", $Down[$i])
    Next
EndFunc

If this works it's the simpliest ways.... but when executes report errors at Array variable.

Problably it's very simply things can be obtain whit a very difficult code ? Strange.

 

*EDIT*

OH MY GOD!! Problably it's not the best solution but it's works....

At first of script i have add this:

Global $File, $Num, $i, $Down, $Down[100]

Apparently this can create 100 spaces for Array!

After do this..... the loop posted above it's apparently it's works.

Edited by DjDiabolik

Share this post


Link to post
Share on other sites
11 minutes ago, Earthshine said:

he said to use _FileReadToArray 

 

what did you not understand about that? read the help file

https://www.autoitscript.com/autoit3/docs/libfunctions/_FileReadToArray.htm

Wait a moment.... _FileReadToArray it's different than FileReadToArray ?

I can try to watch also this solution but apparently this:

Global $File,  $i, $Down, $Down[100]
    Func ReadFile()
    For $i = 1 To 100 Step 1
        $Down[$i] = FileReadLine($File, $i)
        If $Down[$i] = '' then
            ExitLoop
        EndIf
        MsgBox($MB_SYSTEMMODAL, "", $Down[$i])
    Next
EndFunc

It's works... you thinks it's no good option ? Becuase ?

Share this post


Link to post
Share on other sites
7 hours ago, Earthshine said:

Each element of the array is your variable as you wanted. All the work done. You just iterate over the index to get at them 

 

mmmmmmmmm.... Probably not the best route but I got something that works! Also for download section using CURL!

I'm happy to post entire script (edited some parts)..... If you want to give me some advice and you have some improvement to do as well:

#cs ----------------------------------------------------------------------------

 AutoIt Version: 3.3.14.5
 Author:         myName

 Script Function:
    Template AutoIt script.

#ce ----------------------------------------------------------------------------

; Script Start - Add your code below here
#include <FileConstants.au3>
#include <MsgBoxConstants.au3>
#include <WinAPIFiles.au3>
#include <MsgBoxConstants.au3>

Global $User = 'User'
Global $Pass = 'Pass'
Global $NumDown ='50' ;<- Specificare il Numero di Download da fare.... 
Global $UserAgent = '"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:70.0) Gecko/20100101 Firefox/70.0"'
Global $LinkBase = 'https://www.testing.com/downloads/' ;<- Problably obtain error 000 host not found on curl output
;Global $LinkBase = 'https://www.google.com/download/' <- The second url used by me from some test.. alternate if need.
Global $CurlOpz = 'curl -w "%{http_code}\n" --show-error -C - --retry 2 --fail-early --fail --connect-timeout 90 --user ' & $User & ':' & $Pass & ' --user-agent ' & $UserAgent
;InputBox('Variabile', '$CurlOpz', $CurlOpz, '', 1500) ;<- Controllo Variabile
Global $FileToDown = '.\FileToDownload.txt'
Global $File, $Num, $i, $Down, $Down[101], $CmdStr, $Wait, $CheckFileExist, $Errors;<-Look..set for 101 array. i need the first 100 line.

SetFile()
ReadFile()
ListFile()
Download()
CheckErrors()
    

Func SetFile()
    ;$File = ('test.txt') ;<-Skip InputBox seguente <-Test
    ;$File = ('mame.txt') ;<-Skip InputBox seguente <-Another Test
    $File = InputBox("Richiesta", "Inserisci Nome TXT") ;, "", "", -1, -1, 0, 0)
    If @error = 1 Then
        Exit
    EndIf
    $CheckFileExist = FileExists('.\' & $File)
        If $CheckFileExist Then
            
        Else
            MsgBox($MB_SYSTEMMODAL, "", "File non esistente.... riprova!")
            SetFile()
        EndIf
    If $File = '' Then 
    SetFile()
    EndIf
EndFunc

Func ReadFile(); <-This works... simply array and simply loop
    For $i = 1 To $NumDown Step 1
        $Down[$i] = FileReadLine($File, $i)
        If $Down[$i] = '' then ;<- This check.. has fewer lines than the number of downloads set it's exit from set value.
            ExitLoop
        EndIf
        ;MsgBox($MB_SYSTEMMODAL, "", $Down[$i])
    Next
EndFunc

Func ReadFile_Da_Rivedere();<- This is totally test.... it's work but not how i desire. I need to study how _FileReadToArray works...
    $Down = FileReadToArray($File)
    ;$Num = @extended
    ;$Num = 5
    For $i = 0 to $Num - 1
        If $Down[$i] = '.zip' then
            Exit
        EndIf
        $Down[$i] = $Down[$i] & '.zip'
        ;MsgBox($MB_SYSTEMMODAL, "", $Down[$i])
    next
EndFunc

Func ListFile() ;<- Another use... also here array works.
    $TempVariable = FileOpen($FileToDown, 2)
    for $i = 1 to 100 step 1
            If $Down[$i] = '' then ;<- Similar upper... if variable empty exit from loop and for not create empty line.
                ExitLoop
            EndIf
        $Down[$i] = $Down[$i] & '.zip'
        ;InputBox('Variabile', '$Down', $Down[$i], '', 1500) ;<- Controllo Variabile
        FileWrite($FileToDown, $i & '. '& $Down[$i] & @CRLF ) :<- Look here! I know it's not the flair solution. I create a .txt for list file to parse to Download.... lol.
    next
    FileClose($FileToDown)
    ;InputBox('Variabile', '$FileToDown', $FileToDown, '', 1500) ;<- Controllo Variabile
    Run('notepad.exe ' & $FileToDown, '') ;<- After that i open the files whit notepad
    WinWait("[CLASS:Notepad]", "", 10) ;<- I dislike the @Maximize flag. Whit this i popup the notepad windows.
    ;InputBox('Variabile', '$Test1', 'Testing', '', 1500) ;<- Controllo Variabile
EndFunc

Func Download()
    ;$Errors = 0 ;<- Wrong place to set this variable Variable... 
    $TempVariable = FileOpen('.\Failed.txt', 2);<- Open another .txt... here log all failed download
    $TempVariable = MsgBox(36, 'Conferma il Download', 'Desideri Iniziare i Download ?') ;<- Ask to user if want to start download. This appears upper the notepad windows whit the complete list of download...
    If $TempVariable = 7 Then
        WinClose("[CLASS:Notepad]", "")
        Exit
    EndIf
    WinClose("[CLASS:Notepad]", "")
    For $i = 1 to 100 step 1
        If $Down[$i] = '' then
            ExitLoop
        EndIf
        $Wait = Random(5,10,1) ;<- Random wait between one download and another to "mask" the use of curl and script :).
        $CmdStr = ' /c "' & 'ECHO Download Numero: ' & $i & ' - ' & $Down[$i] & ' & ' & $CurlOpz & ' --output .\Download\' & $Down[$i] & ' ' & $LinkBase & $Down[$i] & ' >Log.txt ' & ' & CHOICE /C:AB /T:' & $Wait & ' /D:A >NUL"'; <-Complete string for command prompt and usage curl for every download
        ;InputBox('Variabile', '$CmdStr', $CmdStr, '', 1500) ;<- Controllo Variabile
        RunWait(@Comspec & $CmdStr)
        $CheckFileExist = FileRead(".\Log.txt") ;<- Here read the log.txt created upper here.. it's output of curl command and contain the http result for download. 200 ok.. 404 etc etc.
    Switch $CheckFileExist ;<- Look from here.... i have leave out two alternative... using the switch or use the also valid check whit if..else..then..
        Case 200
        
        Case 401
    ;   If $CheckFileExist = 401 Then
            MsgBox($MB_SYSTEMMODAL, "", 'Errore di Autenticazione o UserName e Password Errati')
            Exit
        Case 404
    ;   ElseIf $CheckFileExist = 404 Then
            FileWrite('.\Failed.txt', $i & '. '& $Down[$i] & ' con errore codice: ' & $CheckFileExist)
            $Errors = $Errors + 1
            MsgBox($MB_SYSTEMMODAL, "", 'File non trovato nel server' & ' - ' & $Down[$i] & '! File Failed.txt creato!', 3)
            ;InputBox('Variabile', '$Errors', $Errors, '', 1500) ;<- Controllo Variabile
            ;MsgBox($MB_SYSTEMMODAL, "", $Errors, 3)
        Case 000
    ;   ElseIf $CheckFileExist = 000 Then
            FileWrite('.\Failed.txt', $i & '. '& $Down[$i] ' con errore codice: ' & $CheckFileExist)
            $Errors = $Errors + 1
            MsgBox($MB_SYSTEMMODAL, "", 'Errore Generico / Sito Non Trovato o altro. Riprova il Download del file ' & $Down[$i] & ' più tardi! File Failed.txt creato!', 3)
            ;InputBox('Variabile', '$Errors', $Errors, '', 1500) ;<- Controllo Variabile
            ;MsgBox($MB_SYSTEMMODAL, "", $Errors, 3)
    EndSwitch
    ;EndIf
    Next
    FileClose('\Failed.txt')
EndFunc

Func CheckErrors() ;<- He report the result of all operation... all works.. i already tested from download 99 Files from the site for which the script was designed. I choose to download 100 files for Test..... result it's 99 because for one i have obtain Error 404 for a know motive. Site as limit to 100 files for days..... 99 completed and the error 404 it's also counted by site like a valid download and I don't know if this is avoidable...
    ;MsgBox($MB_SYSTEMMODAL, "", "Sono sul Func CheckErrors!")
    If $Errors = 0 then
        MsgBox($MB_SYSTEMMODAL, "", "Tutti i File sono stati scaricati correttamente nella cartella .\Download!! Complimenti!!")
    Else
        MsgBox($MB_SYSTEMMODAL, "", "Ci sono stati errori durante i Download!! Tutto è stato loggato nel file Failed.txt!!")
    EndIf   
EndFunc

I have also leave all my commentated test inputbox or msgbox using for test the script ;)

I repeat again.... problably it's not clear... problably it's not fully optimized but it's works........

Edited by DjDiabolik

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

×
×
  • Create New...