LoneWolf_2106

General help - Code improvement - multiple searches in a file

3 posts in this topic

#1 ·  Posted (edited)

Hi everybody,

i want to optimize my search code, because i don't think that my solution is "acceptable" from development perspective, it might be optimized.

I have a text file, i read it and i copy all the entries to an Array, then i have to start a search to see if a specific entry is present. I have about ten different strings to search.

Func FileSearch($file_content_array, $search)
    $j=0
    For $i = 0 To UBound($file_content_array) - 1
            $search_result=StringInStr($file_content_array[$i],$search)
                If $search_result<>0 Then
                    ReDim $searchResultArray[UBound($searchResultArray) + 1]
                    $searchResultArray [$j] = $file_content_array[$i]
                $j+=1
                EndIf

    Next
    Return $searchResultArray
EndFunc

My solution would be ok for a single search, but in case of multiple searches? would it be still good?

I have thought to use a 2D Array, where the first column is the array-item and the second column is "yes" or "no". But what about the searches? Do i have to use 10 times the function?

In case of questions: I have to scan a directory and check whether some files are present or not and then write into another file:"yes, it is present", "no, it is not present".

Thanks in advance

Edited by LoneWolf_2106

Share this post


Link to post
Share on other sites



#2 ·  Posted

Here is a way using a regex to search several string at the same time :

#include <Array.au3>

Local $sInputFile = @ScriptFullPath ; your file
Local $aSearch = ["FileRead", "StringRegExp"] ; string to search for

Local $sContent = FileRead($sInputFile)
Local $sSearchPatten = "(?i)(?:^|\R)\V*(?:"
For $i = 0 To UBound($aSearch) - 1
    $sSearchPatten &= ($i ? "|" : "") & "\Q" & $aSearch[$i] & "\E"
Next
$sSearchPatten &= ")\V*"
ConsoleWrite($sSearchPatten)
Local $aResults = StringRegExp($sContent, $sSearchPatten , 3)

_ArrayDisplay($aResults)

 

Share this post


Link to post
Share on other sites

#3 ·  Posted

I have used a solution with a 2D Array and _ArraySearch

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

  • Similar Content

    • genbadger
      By genbadger
      Hi All,
      I'm not too code savvy but I know this is a simple one! Here's my problem, I have a folder with text files containing gcode. they are appended .nc, .ngc, and .gcode randomly. I can rename them all .ngc which is my preferred file type. In these files there's lines of gcode, carrying commands for a CNC. What I need to do is remove some comments from the beginning and format the text a certain way. I'll show an example of the original file and what I need it to look like. The files can be 20 lines or 10,000 long depending on the part.
      Old text:
      ( Header 1 text                      )
      ( Header 2 text                      )
      G90   (set absolute distance mode)
      G90.1 (set absolute distance mode for arc centers)
      G17   (set active plane to XY)
      G21   (set units to mm)
      #<z_safe> =  0.250 
      #<plunge_feed> =     5 
      (---------------------------------------------------------)
      G0 X 17.2644 Y 1.6127
      M03 
      G1 X 2.2842 Y 8.0674 F 0.01 
      G1 X 15.3642 Y 17.8133
      G1 X 17.2644 Y 1.6127
      M05 
      G0 X 0.0000 Y 0.0000
      M05 
      M02 
       
       
      What it needs to look like:
      G90
      G21
      G0 X17.2644 Y1.6127
      M03
      G1  X2.2842 Y8.0674  <--- copy and paste above the next m05
      G1  X15.3642 Y17.8133
      G1  X17.2644 Y1.6127
      G1  X2.2842 Y8.0674  <--- pasted here
      M05
      G0 X0.000 Y0.000
      M05
      M02
      Some things to note: g90 sets absolute coordinate mode, g21 tets units to mm, g0 is first coordinate to move the tool to. 
      This is an important step: m03 is what turns on a laser. I need the first coordinate after every m03 to be copied to the line above m05 for each chunk of gcode. the very last m05 before the m02 needs to be ignored. There are multiple chunks with m03 x,ys then m05. each chunk is going to have different coordinates after the m03.
       
      I have no idea where to start other than find the line with the wanted string, m03. dont know how to handle m05 though... any help is very much appreciated!
    • phatzilla
      By phatzilla
      Hi gang,
      I'm in a bit of a pickle here, the gist of it is that i have one "main" file with ~200k lines, and literally hundreds of other files each ranging from 1k - 100k lines.
      I need to go through each of the "other" files and (separately) compare them to the "main" file, and save the differences between the two (no duplicates)
       
      The issue is that each comparison (especially if the "other" file has 50+ k lines) takes over a minute each... 
      Is there anyway to cut this time down? As far as i know im using the most optimized array difference script


      Here's a rough mockup of the script im currently using

      note: the main file has all unique lines, and the "other" files wont ever have any lines that *DO NOT* appear in the main file, if that helps
      #include <array.au3> #include <file.au3> global $info_file global $compare_file global $Differece $info_file = FileReadToArray("info-file(200k lines).txt") $compare_file = FileReadToArray("compare-file(100k lines).txt") $Differece = _Diff($info_file, $compare_file, 0) ; get the difference between 2 arrays, NO duplicates _ArrayDisplay($Differece) ;================================================= ; Function Name: _Diff($Set1, $Set2 [, $GetAll=0 [, $Delim=Default]]) ; Description:: Find values in $Set1 that do not occur in $Set2 ; Parameter(s): $Set1 set 1 (1D-array or delimited string) ; $Set2 set 2 (1D-array or delimited string) ; optional: $GetAll 0 - only one occurence of every difference are shown (Default) ; 1 - all differences are shown, allowing duplicates ; optional: $Delim Delimiter for strings (Default use the separator character set by Opt("GUIDataSeparatorChar") ) ; Return Value(s): Succes 1D-array of values from $Set1 that do not occur in $Set2 ; Failure -1 @error set, that was given as array, isn't 1D-array ; Note: Comparison is case-sensitive! - i.e. Number 9 is different to string '9'! ; Author(s): BugFix (bugfix@autoit.de) Modified by ParoXsitiC for Faster _Diff (Formally _GetIntersection) ;================================================= Func _Diff(ByRef $Set1, ByRef $Set2, $GetAll = 0, $Delim = Default) Local $o1 = ObjCreate("System.Collections.ArrayList") Local $o2 = ObjCreate("System.Collections.ArrayList") Local $oDiff1 = ObjCreate("System.Collections.ArrayList") Local $tmp, $i If $GetAll <> 1 Then $GetAll = 0 If $Delim = Default Then $Delim = Opt("GUIDataSeparatorChar") If Not IsArray($Set1) Then If Not StringInStr($Set1, $Delim) Then $o1.Add($Set1) Else $tmp = StringSplit($Set1, $Delim, 1) For $i = 1 To UBound($tmp) - 1 $o1.Add($tmp[$i]) Next EndIf Else If UBound($Set1, 0) > 1 Then Return SetError(1, 0, -1) For $i = 0 To UBound($Set1) - 1 $o1.Add($Set1[$i]) Next EndIf If Not IsArray($Set2) Then If Not StringInStr($Set2, $Delim) Then $o2.Add($Set2) Else $tmp = StringSplit($Set2, $Delim, 1) For $i = 1 To UBound($tmp) - 1 $o2.Add($tmp[$i]) Next EndIf Else If UBound($Set2, 0) > 1 Then Return SetError(1, 0, -1) For $i = 0 To UBound($Set2) - 1 $o2.Add($Set2[$i]) Next EndIf For $tmp In $o1 If Not $o2.Contains($tmp) And ($GetAll Or Not $oDiff1.Contains($tmp)) Then $oDiff1.Add($tmp) Next If $oDiff1.Count <= 0 Then Return 0 Local $aOut[$oDiff1.Count] $i = 0 For $tmp In $oDiff1 $aOut[$i] = $tmp $i += 1 Next Return $aOut EndFunc ;==>_Diff  
    • ken82m
      By ken82m
      Nothing amazing but I use it all the time, I'm surprised something similar hasn't been added to the standard StringReplace.   I've never been any good at regular expressions, I'm sure if I was the whole example below could be done in one line
      But for the simple minded like me here you go    Enjoy $BIOS = _StringMultiReplace(CleanWMIC("bios", "biosversion"), "(|)|{|}", "") Func _StringMultiReplace($zString, $zSearchString, $zReplaceString, $zDelimeter = "|") If $zString = "" OR $zSearchString = "" OR $zDelimeter = "" Then SetError(1) Return $zString EndIf $zArray = StringSplit($zSearchString, $zDelimeter) For $i = 1 to $zArray[0] $zString = StringReplace($zString, $zArray[$i], $zReplaceString) Next Return $zString EndFunc  
    • Kyan
      By Kyan
      Hi, SL3NCK calculates the 7 NCK's levels used for unlocking SL3 phones.
      SL3NCK("0000000000000000000000000000000000000000", "080803080307030003010002020305")
      _output:
      #pw+283037116581614+1# #pw+235518432205471+2# #pw+595388505163502+3# #pw+415333744058839+4# #pw+259299316395048+5# #pw+467723677207791+6# #pw+690485095019780+7# You can test run and see is the same code output as in the following websites:
      http://www.francesco-pompili.it/Hash2Nck.aspx http://nokia-sl3.com/nck.php #include <Crypt.au3> ; #Function# =========================================================================================================== ; Name...........: SL3NCK ; Description ...: Calculates 7 NCK levels for SL3. ; Syntax.........: SL3NCK("TARGET_HASH","MASTER_SP_CODE") ; Return values .: string with 7 levels NCK's. ; Author ........: kyan (autoIT code), oOXTCOo (PHP code). ; Remarks .......: $TargetHash is a string with 40 hex chars. $MasterSP is a string with 30 digits. ; Related .......: SimlFeistel(), _packH() ; Requeires .....: #include <Crypt.au3> ; =============================================================================================================================== Func SL3NCK($TargetHash, $MasterSP) $result = '' $MasterSP = '000000' & StringMid($MasterSP, 0 + 1, 24) For $i = 1 To 7 $hash = _packH('0' & $i & $TargetHash) $hash = StringTrimLeft(StringUpper(_Crypt_HashData($hash, $CALG_SHA1)), 2) $precode8 = StringMid($MasterSP, 0 + 1, 16) $precode7 = StringMid($MasterSP, 17 + 1, 30) For $magic = 0 To 1 $sh = _packH('0' & $magic & StringMid($hash, 0 + 1, 32) & $precode8) $sh = StringTrimLeft(StringUpper(_Crypt_HashData($sh, $CALG_SHA1)), 2) $precode = SimlFeistel($sh, $precode7) $precode7 = $precode $sh = _packH('0' & $magic & StringMid($hash, 0 + 1, 32) & $precode) $sh = StringTrimLeft(StringUpper(_Crypt_HashData($sh, $CALG_SHA1), 2) $precode = SimlFeistel($sh, $precode8, 8) $precode8 = $precode Next $final = $precode8 & $precode7 $x = 1 $nck = '' For $y = 1 To 15 $nck = $nck & StringMid($final, $x + 1, 1) $x += 2 Next $result &= '#pw+' & $nck & '+' & $i & '#' & @CRLF Next Return $result EndFunc ;==>SL3NCK Func SimlFeistel($sh, $precode, $bytes = 7) Local $result = '', $j = 0, $nck = '', $nck2 = '' While ($j < ($bytes * 2)) $nck = StringMid($sh, $j + 1, 1) & StringMid($sh, $j + 2, 1) $nck2 = StringMid($precode, $j + 1, 1) + StringMid($precode, $j + 2, 1) $prenck = Mod((Dec($nck) + Dec($nck2)), 10) $result = $result & '0' & $prenck $j += 2 WEnd Return $result EndFunc ;==>SimlFeistel Func _packH($sInput) Local $sReply = "" For $xx = 1 To StringLen($sInput) Step 2 $sReply &= Chr(Dec(StringMid($sInput, $xx, 2))) Next Return $sReply EndFunc ;==>_packH by Luigi Hope it comes handy for someone
      PS: You can't unlock a phone only with this. Google is your friend.
    • scintilla4evr
      By scintilla4evr
      XCleaner is a simple tool for deleting temporary files and fixing extension problems.
       

      OS X Yosemite-like UI is not a part of this app. For now.
       
      Download

      Moderator note:

      Given the report below be very careful if you decide to download and run this - make sure you take sensible precautions.

      M23