mIRC Home    About    Download    Register    News    Help

Print Thread
Page 1 of 2 1 2
Joined: Aug 2010
Posts: 8
E
Nutrimatic drinks dispenser
OP Offline
Nutrimatic drinks dispenser
E
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 :
Code:
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:
Code:
 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 smile

regards.

Last edited by explodedk; 21/02/11 07:54 PM.
Joined: Jul 2007
Posts: 1,129
T
Hoopy frood
Offline
Hoopy frood
T
Joined: Jul 2007
Posts: 1,129
Code:
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:
Code:
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,145
W
Hoopy frood
Offline
Hoopy frood
W
Joined: Jul 2006
Posts: 4,145
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
T
Hoopy frood
Offline
Hoopy frood
T
Joined: Jul 2007
Posts: 1,129
Originally Posted By: Wims
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
Offline
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...

Code:
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...

Code:
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
T
Hoopy frood
Offline
Hoopy frood
T
Joined: Jul 2007
Posts: 1,129
I can do it like so:
Code:
 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,145
W
Hoopy frood
Offline
Hoopy frood
W
Joined: Jul 2006
Posts: 4,145
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) :
Quote:
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 :
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 :
Originally Posted By: benchread
in 6178 ms
in 6209 ms
in 6177 ms
Originally Posted By: benchread1
in 951 ms
in 921 ms
in 936 ms
for wildcard match and
Quote:
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
T
Hoopy frood
Offline
Hoopy frood
T
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
H
Hoopy frood
Offline
Hoopy frood
H
Joined: Sep 2005
Posts: 2,881
Even faster:

Code:
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
E
Nutrimatic drinks dispenser
OP Offline
Nutrimatic drinks dispenser
E
Joined: Aug 2010
Posts: 8
thanks for all the answers,

what i exactly have is a csv file with text like :

Quote:

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
T
Hoopy frood
Offline
Hoopy frood
T
Joined: Jul 2007
Posts: 1,129
Taken from hixxy's filter suggestion, here is it:
Code:
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
J
Fjord artisan
Offline
Fjord artisan
J
Joined: Feb 2006
Posts: 546
Originally Posted By: hixxy
Even faster:

Code:
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
E
Nutrimatic drinks dispenser
OP Offline
Nutrimatic drinks dispenser
E
Joined: Aug 2010
Posts: 8
Originally Posted By: Tomao
Taken from hixxy's filter suggestion, here is it:
Code:
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
E
Nutrimatic drinks dispenser
OP Offline
Nutrimatic drinks dispenser
E
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
H
Hoopy frood
Offline
Hoopy frood
H
Joined: Sep 2005
Posts: 2,881
Nice smile

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 laugh (yes I know that is because of the inaccuracy of $ticks but still :p)

Joined: Jul 2006
Posts: 4,145
W
Hoopy frood
Offline
Hoopy frood
W
Joined: Jul 2006
Posts: 4,145
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
H
Hoopy frood
Offline
Hoopy frood
H
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 smile

Joined: Jul 2007
Posts: 1,129
T
Hoopy frood
Offline
Hoopy frood
T
Joined: Jul 2007
Posts: 1,129
You two seem to have lost track of this thread so far. :p

Joined: Jul 2006
Posts: 4,145
W
Hoopy frood
Offline
Hoopy frood
W
Joined: Jul 2006
Posts: 4,145
I agree about the theory and with what you said about $read and filter
Quote:
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) :
Code:
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

Quote:
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
H
Hoopy frood
Offline
Hoopy frood
H
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.

Code:
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:

Quote:
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:

Quote:
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)

Page 1 of 2 1 2

Link Copied to Clipboard