|
Joined: Aug 2010
Posts: 8
Nutrimatic drinks dispenser
|
OP
Nutrimatic drinks dispenser
Joined: Aug 2010
Posts: 8 |
hey there. i hope some can help here... i know it's posible to loop and make it look throughout a file... i need to look in the file test.txt the test.txt has 200 lines, which i have defined in a variable like : var %total.lines $lines(test.txt) i now need to loop through the test.txt starting from line 1 and look through every line until i reach line 200. line 1 : bla.bla line 2 : he.he line 3 : bleeeh.bleeeeh etc etc... then i need it to make a variable with the text from the line so i can match it. something like: if (%x isin lol.look.at.him.he.he.sucks) { echo -a %x } where %x is the text from the test.txt hope its understandable regards.
Last edited by explodedk; 21/02/11 07:54 PM.
|
|
|
|
Joined: Jul 2007
Posts: 1,129
Hoopy frood
|
Hoopy frood
Joined: Jul 2007
Posts: 1,129 |
alias find {
var %f = test.txt, %l = $lines(%f)
while (%l) {
var %x = lol|look|at|him|he|sucks
if ($regex($read(%f,n,%l),/( $+ %x $+ )/i)) {
echo -a * I've found one match for: $regml(1)
}
dec %l
}
} Enter /find to search the matches listed in the regex against the test.txt. I assume your intention is to find matches in test.txt against what people say in the channel. If that's the case, you can use: on *:text:*:#: find $1-
on *:action:*:#: find $1-
on *:notice:*:#: find $1-
alias -l find {
var %f = test.txt, %l = $lines(%f)
while (%l) {
if ($regex($1-,/\b( $+ $read(%f,n,%l) $+ )\b/iS)) {
;your command here
}
dec %l
}
}
|
|
|
|
Joined: Jul 2006
Posts: 4,191
Hoopy frood
|
Hoopy frood
Joined: Jul 2006
Posts: 4,191 |
Your loop is very inefficient, $read itself has some functions to compare a string against each line of a file, wildcard or regex are supported.
#mircscripting @ irc.swiftirc.net == the best mIRC help channel
|
|
|
|
Joined: Jul 2007
Posts: 1,129
Hoopy frood
|
Hoopy frood
Joined: Jul 2007
Posts: 1,129 |
Your loop is very inefficient You should point out the inefficiency that you think my example should be improved upon. It's a polite gesture to explain without dropping a line in an in-your-face manner. I know there are -r, -s and -w switches, but a loop is required or it will only return one result. I was borrowing the regex engine to match strings in the test.txt.
|
|
|
|
Joined: Oct 2004
Posts: 8,330
Hoopy frood
|
Hoopy frood
Joined: Oct 2004
Posts: 8,330 |
EDIT: This was meant as a reply to the OP.If you really need every line's information, $fread is probably going to be the most efficient. If you want to search for a given text in the file, then $read() with -r,-s,-w options is probably the best for a single match (as would be the case for most spam/language catchers), or for multiple matches with a search text, /filter is probably the best option. With more details on what the script is meant to do, the best option could be given. But, a real basic script if you don't want to learn anything beyond $read() would be...
alias ReadFile {
var %counter = 1, %total = $lines(file)
while (%counter <= %total) {
var %line = $read(file,%counter)
; Do whatever you want with %line here (such as the following echo command)
echo -a %line
inc %counter
}
}
Replace the two instances of "file" with the filename (and path if it's located somewhere other than $mircdir). Use: /readfile Again, there are better options, but this is about as basic as you can get. Here's a basic spam/language check...
on *:text:*:#: {
var %counter = 1, %total = $0
while (%counter <= %total) {
if ($read(file,w,$+(*,$($+($chr(36),%counter),2),*))) { echo -a spam/language found... | break }
inc %counter
}
}
The file can then be set up as: badword1 badword2 badword3 etc... Of course, such a filter wouldn't just echo something. You'd usually kick/ban the person or something along those lines. This is just a really basic example.
Last edited by Riamus2; 21/02/11 10:57 PM.
Invision Support #Invision on irc.irchighway.net
|
|
|
|
Joined: Jul 2007
Posts: 1,129
Hoopy frood
|
Hoopy frood
Joined: Jul 2007
Posts: 1,129 |
I can do it like so: var %x 1
while $read(file,n,%x) {
if $regex($1-,/\b(\Q $+ $replacecs($v1,\E,\E\\E\Q,$chr(32),\E|\Q) $+ \E)\b/iS) {
;cmd
}
inc %x
}
|
|
|
|
Joined: Jul 2006
Posts: 4,191
Hoopy frood
|
Hoopy frood
Joined: Jul 2006
Posts: 4,191 |
Sorry, the way you used $read is the bad thing, even if we do need the loop for multiple matches when using $read, it should never be used this way (getting each line and match with and if statement), look at this exemple. Using this file ($mircdirtest.txt) : aaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbb ccccccccccccccccccccccccccccc ddddddddddddddddddddddddddddd eeeeeeeeeeeeeeeeeeeeeeeeeeeee fffffffffffffffffffffffffffff ggggggggggggggggggggggggggggg hhhhhhhhhhhhhhhhhhhhhhhhhhhhh iiiiiiiiiiiiiiiiiiiiiiiiiiiii jjjjjjjjjjjjjjjjjjjjjjjjjjjjj kkkkkkkkkkkkkkkkkkkkkkkkkkkkk lllllllllllllllllllllllllllll }}}}}}}}}}}}}}}}}}}}}}}}}}}}} mmmmmmmmmmmmmmmmmmmmmmmmmmmmm nnnnnnnnnnnnnnnnnnnnnnnnnnnnn ooooooooooooooooooooooooooooo ppppppppppppppppppppppppppppp qqqqqqqqqqqqqqqqqqqqqqqqqqqqq rrrrrrrrrrrrrrrrrrrrrrrrrrrrr sssssssssssssssssssssssssssss ttttttttttttttttttttttttttttt uuuuuuuuuuuuuuuuuuuuuuuuuuuuu vvvvvvvvvvvvvvvvvvvvvvvvvvvvv wwwwwwwwwwwwwwwwwwwwwwwwwwwww xxxxxxxxxxxxxxxxxxxxxxxxxxxxx yyyyyyyyyyyyyyyyyyyyyyyyyyyyy zzzzzzzzzzzzzzzzzzzzzzzzzzzzz {{{{{{{{{{{{{{{{{{{{{{{{{{{{{ ||||||||||||||||||||||||||||| }}}}}}}}}}}}}}}}}}}}}}}}}}}}} And this code : alias benchread {
var %t $ticks ,%a 1000,%l $lines(test.txt)
while (%a) {
var %b 1
while (%b <= %l) {
if (*}}}}}}}}}}* iswm $read(test.txt,n,%b)) noop match the file on line %b : $v1
; if ($regex($read(test.txt,n,%b),/\Q}}}}}}}}}}\E/i) noop match the file on line %b : $v1
inc %b
}
dec %a
}
echo -a in $calc($ticks - %t) ms
}
alias benchread1 {
var %t $ticks ,%a 1000
while (%a) {
var %l 1
while ($read(test.txt, wn, *}}}}}}}}}}*,%l) != $null) {
noop match the file on line $readn : $v1
%l = $readn + 1
}
; while ($read(test.txt, rn, /}}}}}}}}}}/i,%l) != $null) { noop match the file on line $readn : $v1 | %l = $readn +1 }
dec %a
}
echo -a in $calc($ticks - %t) ms
} I get : in 6178 ms in 6209 ms in 6177 ms in 951 ms in 921 ms in 936 ms for wildcard match and in 6895 ms in 6896 ms in 6896 ms - in 1045 ms in 1092 ms in 1060 ms for regex, as you can see using $read with the s or w switch and the N feature, that start searching at the Nth line of the file is far better edit : this is just an exemple, of course /filter is better than a loop if multiple matches are to be done.
Last edited by Wims; 22/02/11 12:04 AM.
#mircscripting @ irc.swiftirc.net == the best mIRC help channel
|
|
|
|
Joined: Jul 2007
Posts: 1,129
Hoopy frood
|
Hoopy frood
Joined: Jul 2007
Posts: 1,129 |
Well, I thank you for your effort, Wims. I'll bear that in mind. :-)
|
|
|
|
Joined: Sep 2005
Posts: 2,881
Hoopy frood
|
Hoopy frood
Joined: Sep 2005
Posts: 2,881 |
Even faster:
alias _test { noop $1- }
alias benchread1 {
var %ticks = $ticks
filter -fk test.txt _test *}}}}}}}}}}*
echo -a * Test completed in: $calc($ticks - %ticks) ms with $filtered results.
}
|
|
|
|
Joined: Aug 2010
Posts: 8
Nutrimatic drinks dispenser
|
OP
Nutrimatic drinks dispenser
Joined: Aug 2010
Posts: 8 |
thanks for all the answers, what i exactly have is a csv file with text like : prison.break;scripted;us csi.miami;scripted;us the.mentalist;scripted;us
so there will be no lines that has same text... i tried the alias readfile, but that makes my mirc stall and all i can do is close it from task manager... if af ilter is the best / fastes way to go , i'd like that indeed .
|
|
|
|
Joined: Jul 2007
Posts: 1,129
Hoopy frood
|
Hoopy frood
Joined: Jul 2007
Posts: 1,129 |
Taken from hixxy's filter suggestion, here is it: alias _test {
var %x = lol.look.at.him.he.he.sucks
if ($isfile(test.txt)) && ($isid) { echo -a * Match Found: $1- }
else { filter -fk test.txt _test $+(*,%x,*)) }
}
|
|
|
|
Joined: Feb 2006
Posts: 546
Fjord artisan
|
Fjord artisan
Joined: Feb 2006
Posts: 546 |
Even faster:
alias _test { noop $1- }
alias benchread1 {
var %ticks = $ticks
filter -fk test.txt _test *}}}}}}}}}}*
echo -a * Test completed in: $calc($ticks - %ticks) ms with $filtered results.
} that still requires mIRC to evaluate $_test($1-) for $1- = each line in turn :P knowing that mIRC evaluates $<arg>($1-) where <arg> is the argument you've supplied, necessarily a single word, we can start throwing out suggestions as to what value of <arg> we can select that takes the least amount of work to evaluate. for a while i would've suggested <arg> = () which causes mIRC to evaluate $()($1-) for each matching line. $() produces $null of course, and the bit on the end is simply ignored to save mIRC the trouble of evaluating $1-. however, after a bit testing, it seems <arg> = ~~ (producing $~~($1-) as the piece of code to evaluate repeatedly) is slightly quicker. $~identifier(), as we know, avoids calling custom aliases and also suppresses the identifier warning if 'identifier' doesn't exist as an internal identifier. generally, $abc won't be evaluated if $~ident($abc) is used and 'ident' doesn't exist, so like before we avoid $1- having to be evaluated. i dare say $~~() is unlikely to ever be introduced as an internal identifier, and for some reason mIRC seems to be able to recognize that $~~() doesn't exist slightly quicker than, for example, $~a() or $~b() etc.
"The only excuse for making a useless script is that one admires it intensely" - Oscar Wilde
|
|
|
|
Joined: Aug 2010
Posts: 8
Nutrimatic drinks dispenser
|
OP
Nutrimatic drinks dispenser
Joined: Aug 2010
Posts: 8 |
Taken from hixxy's filter suggestion, here is it: alias _test {
var %x = lol.look.at.him.he.he.sucks
if ($isfile(test.txt)) && ($isid) { echo -a * Match Found: $1- }
else { filter -fk test.txt _test $+(*,%x,*)) }
} i can't get this to work. it aint echo'in anything. however if i use var %x he.he it finds it, but when he.he is used in a sentence, it returns $null i have in my file e.g : UEFA.CHAMPIONS.LEAGUE;SPORTS;SOCCER and i need to be able to do a /test UEFA.CHAMPIONS.LEAGUE.2010.2011 and have it crosscheck the test.txt file for uefa.champions.league only. however 2010.2011 could be random text in the same word...
|
|
|
|
Joined: Aug 2010
Posts: 8
Nutrimatic drinks dispenser
|
OP
Nutrimatic drinks dispenser
Joined: Aug 2010
Posts: 8 |
as far as i can see all the replies work the other way around...
i have text in the txt file like
prison.break;scripted;us the.mentalist;scripted;us uefa.champions.league;sports;n/a
and then my trigger (lets call it %y) is like: var %y uefa.champions.league.2010.2011.arsenal.vs.barcelona
or
var %y uefa.champions.league.highlights
then i need it to set %x as uefa.champions.league and if (%x isin %y) { echo -a * MATCH FOUND %x matches %y }
|
|
|
|
Joined: Sep 2005
Posts: 2,881
Hoopy frood
|
Hoopy frood
Joined: Sep 2005
Posts: 2,881 |
Nice The /filter method (both mine and yours) yields search times of 0ms for me on Wims' test file every time I run it, can't get much faster (yes I know that is because of the inaccuracy of $ticks but still :p)
|
|
|
|
Joined: Jul 2006
Posts: 4,191
Hoopy frood
|
Hoopy frood
Joined: Jul 2006
Posts: 4,191 |
Yeah I know filter is faster, I was just showing how $read should be used, for exemple if you only want N matches, filter could be slower than using $read on a big file in that case
#mircscripting @ irc.swiftirc.net == the best mIRC help channel
|
|
|
|
Joined: Sep 2005
Posts: 2,881
Hoopy frood
|
Hoopy frood
Joined: Sep 2005
Posts: 2,881 |
In theory /filter will be faster for more than one match, $read will be faster for only one match. $read opens a file handle, reads from the start to the position in the file which matches the line number/search parameters you specify, then closes the file handle. /filter opens a file handle, reads from the start to the end of the file, matching the contents as it goes, then closes the file handle. If you call $read more than once, it opens the file handle, reads from the start of the file and then closes it each time -- all of which are overheads that /filter doesn't have. Multiple $reads could potentially be faster if the matches are found near the start of the file, as it will have less data to go through than /filter. In any event, was just offering another alternative
|
|
|
|
Joined: Jul 2007
Posts: 1,129
Hoopy frood
|
Hoopy frood
Joined: Jul 2007
Posts: 1,129 |
You two seem to have lost track of this thread so far. :p
|
|
|
|
Joined: Jul 2006
Posts: 4,191
Hoopy frood
|
Hoopy frood
Joined: Jul 2006
Posts: 4,191 |
I agree about the theory and with what you said about $read and filter Multiple $reads could potentially be faster if the matches are found near the start of the file, as it will have less data to go through than /filter. I made another test to check that : %n is the number of match we want from the start of the file (just some copy/paste of the previous file) : alias benchread1 {
var %t $ticks ,%a 1000
while (%a) {
var %l 1,%n 2
while ($read(test.txt, wn, *}}}}}}}}}}*,%l) != $null) && (%n) { noop match the file on line $readn : $v1 | %l = $readn + 1 | dec %n }
dec %a
}
echo -a in $calc($ticks - %t) ms
}
alias _test if (%n) noop match the file on line $1 : $2- | dec %n
alias benchread2 {
var %t $ticks,%a 1000
while (%a) {
set -u %n 2
filter -fnk test.txt _test *}}}}}}}}}}*
dec %a
}
echo -a in $calc($ticks - %t) ms
} Using this file, /filter is slower than $read for %n <= 4 in my test In any event, was just offering another alternative Yeah, it's fine, but the purpose of my post was to compare two methods involving $read, not to do the job the fastest ways possible
#mircscripting @ irc.swiftirc.net == the best mIRC help channel
|
|
|
|
Joined: Sep 2005
Posts: 2,881
Hoopy frood
|
Hoopy frood
Joined: Sep 2005
Posts: 2,881 |
Really? Filter beats $read every time for me. I've slightly adjusted your benchmark aliases so that it tells you which method it's benchmarking in the echo. I've also added a /benchtest command to run each bench 10 times. alias benchread1 {
var %t $ticks ,%a 1000
while (%a) {
var %l 1,%n 2
while ($read(test.txt, wn, *}}}}}}}}}}*,%l) != $null) && (%n) { noop match the file on line $readn : $v1 | %l = $readn + 1 | dec %n }
dec %a
}
echo -a in $calc($ticks - %t) ms ($read)
}
alias _test if (%n) noop match the file on line $1 : $2- | dec %n
alias benchread2 {
var %t $ticks,%a 1000
while (%a) {
set -u %n 2
filter -fnk test.txt _test *}}}}}}}}}}*
dec %a
}
echo -a in $calc($ticks - %t) ms (/filter)
}
alias benchtest {
var %i = 10
while (%i) {
benchread1
benchread2
if (%i > 1) { linesep -a }
dec %i
}
} Here's my results for %n = 2: in 1344 ms ($read) in 562 ms (/filter) - in 1344 ms ($read) in 578 ms (/filter) - in 1359 ms ($read) in 578 ms (/filter) - in 1375 ms ($read) in 563 ms (/filter) - in 1359 ms ($read) in 578 ms (/filter) - in 1344 ms ($read) in 578 ms (/filter) - in 1359 ms ($read) in 579 ms (/filter) - in 1343 ms ($read) in 578 ms (/filter) - in 1344 ms ($read) in 578 ms (/filter) - in 1344 ms ($read) in 578 ms (/filter) And with %n = 1: in 844 ms ($read) in 578 ms (/filter) - in 859 ms ($read) in 563 ms (/filter) - in 843 ms ($read) in 578 ms (/filter) - in 844 ms ($read) in 563 ms (/filter) - in 843 ms ($read) in 579 ms (/filter) - in 843 ms ($read) in 563 ms (/filter) - in 844 ms ($read) in 562 ms (/filter) - in 844 ms ($read) in 562 ms (/filter) - in 844 ms ($read) in 563 ms (/filter) - in 843 ms ($read) in 578 ms (/filter)
|
|
|
|
|