email search in text file

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
Sarah92
Posts: 28
Joined: 02 Nov 2017, 19:02

email search in text file

23 Jan 2018, 08:33

Hello, been workin on something for awhile now and haven't been able to achieve what i have in mind, i work in an organization that deals with names, and what i want to do is to be able to find names that have the names i search and keep them in different files, for example


the coding below:

{
Loop, parse, A_LoopReadLine, %A_Tab%
{
send %A_loopfield%{enter}
}
}
Last edited by Sarah92 on 05 Jan 2019, 08:24, edited 2 times in total.
MaxAstro
Posts: 557
Joined: 05 Oct 2016, 13:00

Re: search list

23 Jan 2018, 10:32

Depending on the number of letters you are searching for and the number of names you are searching, this could be a time consuming function. That said...

Code: Select all

InputVar := "SMADA"		; Use any method you prefer for getting the initial input
SearchArray := {}
AnswerList := {}	; Create a couple arrays that will be used later
Loop, % StrLen(InputVar)	; Loop a number of times equal to the number of letters entered
	SearchArray[A_Index] := SubStr(InputVar, A_Index, 1)	; Split the input variable into an array - "SMADA" becomes {1 : S, 2 : M, 3 : A, 4 : D, 5 : A}
Loop, read, C:\testfolder\names.txt	; Change this to the location of the names.txt file on your computer
{
	NameMatch := true	; This variable gets used later
	Loop, parse, A_LoopReadLine	; If you don't use a delimiter here, it will read the name letter by letter
	{
		if A_LoopField is not alpha
			continue	; Skip any characters that aren't letters
		MatchFound := false
		for key, value in SearchArray		; This loops through each letter of the array created earlier
			if (value = A_LoopField)
			{
				MatchFound := true
				break	; A match was found, stop looking
			}
		if (!MatchFound)
		{
			NameMatch := false
			break	; If there are any letters that aren't in the search, toss out this name
		}
	}
	if (NameMatch)
		AnswerList.Push(A_LoopReadLine)	; If there was a match, add it to the list of answers
}
for key, value in AnswerList
{
	; By default this just pops up a messagebox displaying each match one at a time
	; Change this code to whatever you want to do with the matched names
	MsgBox %value%
}
Sarah92
Posts: 28
Joined: 02 Nov 2017, 19:02

Re: search list

23 Jan 2018, 12:49

MaxAstro wrote:Depending on the number of letters you are searching for and the number of names you are searching, this could be a time consuming function. That said...

Code: Select all

InputVar := "SMADA"		; Use any method you prefer for getting the initial input
SearchArray := {}
AnswerList := {}	; Create a couple arrays that will be used later
Loop, % StrLen(InputVar)	; Loop a number of times equal to the number of letters entered
	SearchArray[A_Index] := SubStr(InputVar, A_Index, 1)	; Split the input variable into an array - "SMADA" becomes {1 : S, 2 : M, 3 : A, 4 : D, 5 : A}
Loop, read, C:\testfolder\names.txt	; Change this to the location of the names.txt file on your computer
{
	NameMatch := true	; This variable gets used later
	Loop, parse, A_LoopReadLine	; If you don't use a delimiter here, it will read the name letter by letter
	{
		if A_LoopField is not alpha
			continue	; Skip any characters that aren't letters
		MatchFound := false
		for key, value in SearchArray		; This loops through each letter of the array created earlier
			if (value = A_LoopField)
			{
				MatchFound := true
				break	; A match was found, stop looking
			}
		if (!MatchFound)
		{
			NameMatch := false
			break	; If there are any letters that aren't in the search, toss out this name
		}
	}
	if (NameMatch)
		AnswerList.Push(A_LoopReadLine)	; If there was a match, add it to the list of answers
}
for key, value in AnswerList
{
	; By default this just pops up a messagebox displaying each match one at a time
	; Change this code to whatever you want to do with the matched names
	MsgBox %value%
}
Last edited by Sarah92 on 31 Jan 2018, 11:33, edited 1 time in total.
gregster
Posts: 9021
Joined: 30 Sep 2013, 06:48

Re: search list

23 Jan 2018, 13:24

Have you looked at the docs? ... there is a suspiciously named command called InputBox.
Odlanir
Posts: 659
Joined: 20 Oct 2016, 08:20

Re: search list

23 Jan 2018, 13:36

Some like this? Is just a starting point.
Put your text file in Fileread.
For testing purpose I've used a web file.

Code: Select all

IfNotExist, EnglishNames.txt
URLDownloadToFile, http://scrapmaker.com/data/wordlists/names/male-names.txt,EnglishNames.txt
FileRead, nam, EnglishNames.txt
n := []
Loop, Parse, nam, `n, `r
{   
   IfNotInString, A_LoopField, #
      n.Push(A_LoopField)
}   
gui,add,edit,r1 w200 vINP gINP
gui, add, edit, r40 w200 vOUT
gui, add, Button, gBut w200, Save List
gui Show
return

But:
   gui,Submit, NoHide
   FileDelete, Names.txt
   FileAppend, %OUT%, Names.txt
   run, Names.txt
return
INP:
   gui,Submit, NoHide
   GuiControl,,Edit2,
   OL := ""
   loop, % n.maxindex() {
      if ( RegExMatch(n[a_index], "i)" . inp)) {
         ol .= n[a_index]  "`n"
      }      
   }
   GuiControl,,Edit2, %ol%
return

ExitApp

esc::
GuiClose:
GuiEscape:
   ExitApp
____________________________________________________________________________
Windows 10 Pro 64 bit - Autohotkey v1.1.30.01 64-bit Unicode
Sarah92
Posts: 28
Joined: 02 Nov 2017, 19:02

Re: search list

23 Jan 2018, 13:54

gregster wrote:Have you looked at the docs? ... there is a suspiciously named command called InputBox.
been able to get that. inputbox, names, enter names. but when i run the script and the box pops up after typin the name and hittin ok, the script exits itself. any help?
gregster
Posts: 9021
Joined: 30 Sep 2013, 06:48

Re: search list

23 Jan 2018, 15:03

Sarah92 wrote:
gregster wrote:Have you looked at the docs? ... there is a suspiciously named command called InputBox.
been able to get that. inputbox, names, enter names. but when i run the script and the box pops up after typin the name and hittin ok, the script exits itself. any help?
Which script? If the script only consists of this one line, that would be the expected result. Your input would be in the variable names... that would be similar to MaxAstro's line InputVar := "SMADA", only that you are now using a different variable name. Now you have to work with that... what have you tried? Does Max' script work (I haven't tested it) ? Have you tried to add the inputbox there? Mind the variable names!
Sarah92
Posts: 28
Joined: 02 Nov 2017, 19:02

Re: search list

23 Jan 2018, 15:24

Odlanir wrote:Some like this? Is just a starting point.
Put your text file in Fileread.
For testing purpose I've used a web file.

Code: Select all

IfNotExist, EnglishNames.txt
URLDownloadToFile, http://scrapmaker.com/data/wordlists/names/male-names.txt,EnglishNames.txt
FileRead, nam, EnglishNames.txt
n := []
Loop, Parse, nam, `n, `r
{   
   IfNotInString, A_LoopField, #
      n.Push(A_LoopField)
}   
gui,add,edit,r1 w200 vINP gINP
gui, add, edit, r40 w200 vOUT
gui, add, Button, gBut w200, Save List
gui Show
return

But:
   gui,Submit, NoHide
   FileDelete, Names.txt
   FileAppend, %OUT%, Names.txt
   run, Names.txt
return
INP:
   gui,Submit, NoHide
   GuiControl,,Edit2,
   OL := ""
   loop, % n.maxindex() {
      if ( RegExMatch(n[a_index], "i)" . inp)) {
         ol .= n[a_index]  "`n"
      }      
   }
   GuiControl,,Edit2, %ol%
return

ExitApp

esc::
GuiClose:
GuiEscape:
   ExitApp
Last edited by Sarah92 on 31 Jan 2018, 11:34, edited 1 time in total.
garry
Posts: 3770
Joined: 22 Dec 2013, 12:50

Re: search list

23 Jan 2018, 15:40

little bit confused
;- it doesn't find kati or kat >> only kate and katie
example from MaxAstro with input (GUI )

Code: Select all

;- it doesn't find kati or kat  >> only kate and katie

#warn
name1=Test
f1 := A_ScriptDir . "\names.txt"
IfNotExist,% f1
{
e4x=
 (LTrim Join`r`n % `
adams
adam
adas
adi
kate
katie
michael
 )
fileappend,%e4x%,%f1%
}


Gui,2:default
Gui,2:Font,s12 ,Lucida Console
Gui,2:Color,Black
Gui,2:Color,ControlColor, Black
Gui,2:add,Edit,   x20   y10 w140 h25  cGray   right  vInputvar ,SMADA
Gui,2:add,Edit,   x20   y40 w250 h150 cYellow right  vOut
Gui,2:add,Button, x170  y10 w100 h27 gA1,Find
Gui,2:Show,x1 y1 w300 h200 ,%name1%
Return
;-------------------------------
2GuiClose:
ExitApp

a1:
Gui,2:submit,nohide
;InputVar := "SMADA"	                                	; Use any method you prefer for getting the initial input
SearchArray := {}
AnswerList  := {}
e:=
value:=
namematch:=
matchfound:=
GuiControl,2:Text,Out,
                                       	; Create a couple arrays that will be used later
Loop, % StrLen(InputVar)	                                ; Loop a number of times equal to the number of letters entered
	SearchArray[A_Index] := SubStr(InputVar, A_Index, 1)	; Split the input variable into an array - "SMADA" becomes {1 : S, 2 : M, 3 : A, 4 : D, 5 : A}
Loop, read, %f1%                	                        ; Change this to the location of the names.txt file on your computer
{
	NameMatch := true	                                ; This variable gets used later
	Loop, parse, A_LoopReadLine, 	                        ; If you don't use a delimiter here, it will read the name letter by letter
	{
		if A_LoopField is not alpha
			continue	                        ; Skip any characters that aren't letters
		MatchFound := false
		for key, value in SearchArray		        ; This loops through each letter of the array created earlier
			if (value = A_LoopField)
			{
				MatchFound := true
				break	                        ; A match was found, stop looking
			}
		if (!MatchFound)
		{
			NameMatch := false
			break	                                ; If there are any letters that aren't in the search, toss out this name
		}
	}
	if (NameMatch)
             {
             e .= a_loopreadline . "`n"
             GuiControl,2:Text,Out,%e%
	     AnswerList.Push(A_LoopReadLine)             	; If there was a match, add it to the list of answers
             }
}

for key, value in AnswerList
{
	; By default this just pops up a messagebox displaying each match one at a time
	; Change this code to whatever you want to do with the matched names
	;MsgBox %value%                                     ;- show msgbox 
}
;============================================================

Sarah92
Posts: 28
Joined: 02 Nov 2017, 19:02

Re: search list

24 Jan 2018, 03:20

garry wrote:little bit confused
;- it doesn't find kati or kat >> only kate and katie
example from MaxAstro with input (GUI )

Code: Select all

;- it doesn't find kati or kat  >> only kate and katie

#warn
name1=Test
f1 := A_ScriptDir . "\names.txt"
IfNotExist,% f1
{
e4x=
 (LTrim Join`r`n % `
adams
adam
adas
adi
kate
katie
michael
 )
fileappend,%e4x%,%f1%
}


Gui,2:default
Gui,2:Font,s12 ,Lucida Console
Gui,2:Color,Black
Gui,2:Color,ControlColor, Black
Gui,2:add,Edit,   x20   y10 w140 h25  cGray   right  vInputvar ,SMADA
Gui,2:add,Edit,   x20   y40 w250 h150 cYellow right  vOut
Gui,2:add,Button, x170  y10 w100 h27 gA1,Find
Gui,2:Show,x1 y1 w300 h200 ,%name1%
Return
;-------------------------------
2GuiClose:
ExitApp

a1:
Gui,2:submit,nohide
;InputVar := "SMADA"	                                	; Use any method you prefer for getting the initial input
SearchArray := {}
AnswerList  := {}
e:=
value:=
namematch:=
matchfound:=
GuiControl,2:Text,Out,
                                       	; Create a couple arrays that will be used later
Loop, % StrLen(InputVar)	                                ; Loop a number of times equal to the number of letters entered
	SearchArray[A_Index] := SubStr(InputVar, A_Index, 1)	; Split the input variable into an array - "SMADA" becomes {1 : S, 2 : M, 3 : A, 4 : D, 5 : A}
Loop, read, %f1%                	                        ; Change this to the location of the names.txt file on your computer
{
	NameMatch := true	                                ; This variable gets used later
	Loop, parse, A_LoopReadLine, 	                        ; If you don't use a delimiter here, it will read the name letter by letter
	{
		if A_LoopField is not alpha
			continue	                        ; Skip any characters that aren't letters
		MatchFound := false
		for key, value in SearchArray		        ; This loops through each letter of the array created earlier
			if (value = A_LoopField)
			{
				MatchFound := true
				break	                        ; A match was found, stop looking
			}
		if (!MatchFound)
		{
			NameMatch := false
			break	                                ; If there are any letters that aren't in the search, toss out this name
		}
	}
	if (NameMatch)
             {
             e .= a_loopreadline . "`n"
             GuiControl,2:Text,Out,%e%
	     AnswerList.Push(A_LoopReadLine)             	; If there was a match, add it to the list of answers
             }
}

for key, value in AnswerList
{
	; By default this just pops up a messagebox displaying each match one at a time
	; Change this code to whatever you want to do with the matched names
	;MsgBox %value%                                     ;- show msgbox 
}
;============================================================

Last edited by Sarah92 on 09 Feb 2018, 18:11, edited 1 time in total.
Sarah92
Posts: 28
Joined: 02 Nov 2017, 19:02

Re: search list

24 Jan 2018, 03:22

MaxAstro wrote:Depending on the number of letters you are searching for and the number of names you are searching, this could be a time consuming function. That said...

Code: Select all

InputVar := "SMADA"		; Use any method you prefer for getting the initial input
SearchArray := {}
AnswerList := {}	; Create a couple arrays that will be used later
Loop, % StrLen(InputVar)	; Loop a number of times equal to the number of letters entered
	SearchArray[A_Index] := SubStr(InputVar, A_Index, 1)	; Split the input variable into an array - "SMADA" becomes {1 : S, 2 : M, 3 : A, 4 : D, 5 : A}
Loop, read, C:\testfolder\names.txt	; Change this to the location of the names.txt file on your computer
{
	NameMatch := true	; This variable gets used later
	Loop, parse, A_LoopReadLine	; If you don't use a delimiter here, it will read the name letter by letter
	{
		if A_LoopField is not alpha
			continue	; Skip any characters that aren't letters
		MatchFound := false
		for key, value in SearchArray		; This loops through each letter of the array created earlier
			if (value = A_LoopField)
			{
				MatchFound := true
				break	; A match was found, stop looking
			}
		if (!MatchFound)
		{
			NameMatch := false
			break	; If there are any letters that aren't in the search, toss out this name
		}
	}
	if (NameMatch)
		AnswerList.Push(A_LoopReadLine)	; If there was a match, add it to the list of answers
}
for key, value in AnswerList
{
	; By default this just pops up a messagebox displaying each match one at a time
	; Change this code to whatever you want to do with the matched names
	MsgBox %value%
}
Last edited by Sarah92 on 09 Feb 2018, 18:11, edited 1 time in total.
MaxAstro
Posts: 557
Joined: 05 Oct 2016, 13:00

Re: search list

24 Jan 2018, 15:45

Hmm... That is a non-trivial problem. Search theory is basically an entire branch of programming, and writing complex search functions is a bit outside of my wheelhouse. There's a lot of questions to tackle, like what percent of a match should be counted. Matching a non-ordered search is also extra complex since you are effectively looking for every possible anagram of a word. SMADA should find Adam, Sam, Ada, and Damas, but it shouldn't find Samaad... or should it? Are you looking for every word that contains all of those letters, or only words that contain only those letters?

I guess mostly I don't understand your use case - why do you need to find every name that is an anagram of the search query? Why aren't you looking for partial matches instead? I'm trying to come up with a situation where "a seach for ADAMS returns SAM as a match but doesn't return ADAMST" is useful but I'm not seeing it.
Sarah92
Posts: 28
Joined: 02 Nov 2017, 19:02

Re: search list

25 Jan 2018, 12:31

.
Last edited by Sarah92 on 09 Feb 2018, 18:12, edited 1 time in total.
MaxAstro
Posts: 557
Joined: 05 Oct 2016, 13:00

Re: search list

25 Jan 2018, 17:39

Well, that's an odd request but I suppose possible... Probably need to have it pull each letter from the array as it finds it, I guess? Let's see, this should do it.

Code: Select all

InputVar := "SMADA"		; Use any method you prefer for getting the initial input
SearchArray := {}
AnswerList := {}	; Create a couple arrays that will be used later
Loop, % StrLen(InputVar)	; Loop a number of times equal to the number of letters entered
	SearchArray[A_Index] := SubStr(InputVar, A_Index, 1)	; Split the input variable into an array - "SMADA" becomes {1 : S, 2 : M, 3 : A, 4 : D, 5 : A}
Loop, read, C:\testfolder\names.txt	; Change this to the location of the names.txt file on your computer
{
	NameMatch := true	; This variable gets used later
	SearchClone := {}
	SearchClone := SearchArray.Clone()	; Make a copy of the search array so that we can edit the copy
	Loop, parse, A_LoopReadLine	; If you don't use a delimiter here, it will read the name letter by letter
	{
		if A_LoopField is not alpha
			continue	; Skip any characters that aren't letters
		MatchFound := false
		for key, value in SearchClone		; This loops through each letter of the array created earlier
			if (value = A_LoopField)
			{
				MatchFound := true
				SearchClone.Delete(key)	; Remove successful matches from the search
				break	; A match was found, stop looking
			}
		if (!MatchFound)
		{
			NameMatch := false
			break	; If there are any letters that aren't in the search, toss out this name
		}
	}
	if (NameMatch)
		AnswerList.Push(A_LoopReadLine)	; If there was a match, add it to the list of answers
}
for key, value in AnswerList
{
	; By default this just pops up a messagebox displaying each match one at a time
	; Change this code to whatever you want to do with the matched names
	MsgBox %value%
}
Sarah92
Posts: 28
Joined: 02 Nov 2017, 19:02

Re: search list

26 Jan 2018, 04:49

thanks max thats exactly what i want, am very greatful. Thanks for ur time.

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: jeves, mikeyww, Thorlian and 281 guests