mIRC Home    About    Download    Register    News    Help

Print Thread
Joined: Oct 2005
Posts: 16
S
saxorr Offline OP
Pikka bird
OP Offline
Pikka bird
S
Joined: Oct 2005
Posts: 16
Hey there,

Just wondering if there was a way for $read to start searching from the very bottom line, then going up on the file.

Thanks in advance.

Joined: Apr 2004
Posts: 759
M
Hoopy frood
Offline
Hoopy frood
M
Joined: Apr 2004
Posts: 759
Code:
...
var %len = $lines(yourfile)
while %len > 0 {
   echo -a $read(yourfile,%len)
   dec %len
  } 
...


$maybe
Joined: Sep 2003
Posts: 4,230
D
Hoopy frood
Offline
Hoopy frood
D
Joined: Sep 2003
Posts: 4,230
No clean and simple method i can think of.

You could however do something like this

filter -ffcn YOURFILE.txt TEMPFILE.txt
filter -ffceut 1 32 TEMPFILE.txt TEMPFILE.txt

You now have a file called TEMPFILE.txt (obviously call it what ever you want)
The format of each line in it is <line#> <linecontents> and its in reverse order

ie: if your original file was
bob 87
peter 97
bob 102
bill 67

the TEMPFILE.txt well look like
4 bill 67
3 bob 102
2 peter 97
1 bob 87

so assuming you were after finding lines containing "bob" you could replace $read(YOURFILE.txt,ntw,*bob*,%i) with $read(TEMPFILE.txt,ntw,& *bob*,%i)
ex
Code:
filter -ffcn YOURFILE.txt TEMPFILE.txt
filter -ffceut 1 32 TEMPFILE.txt TEMPFILE.txt
var %i = 1
while ($read(TEMPFILE.txt,ntw,&amp; *bob*,%i)) {
  var %original.line.number = $gettok($read(TEMPFILE.txt,ntw,&amp; *bob*,%i),1,32)
  var %original.line.text    = $gettok($read(TEMPFILE.txt,ntw,&amp; *bob*,%i),2-,32)
  echo -a line number %original.line.number contents %original.line.text
  var %i = $readn | inc %i
}



Esentially your creating a second file in reverse order with the line number of the original line at the start (this is needed since its how you reverse the orer of the lines using filter)
You can then search this file forwardly with confidence that it represents the orginal file from the bottom up.

PS: the "*bob*" being replaced with "& *bob*" is becuase the "& " sucks up the linenumber and the space, and ensures any wild search you do doestn accidently match a line number, as you might search for lines containging "23" and would otherwise cact lines 23 123 1023 1235 etc etc.

Joined: Oct 2005
Posts: 16
S
saxorr Offline OP
Pikka bird
OP Offline
Pikka bird
S
Joined: Oct 2005
Posts: 16
Thanks DaveC, very smart way of doing it smile

edit-
Ah my bad, asked whether there was a way to do it without the numbers in the start of the lines, but obviously cant for rotation.

Last edited by saxorr; 27/11/05 04:05 PM.
Joined: Feb 2004
Posts: 2,019
Hoopy frood
Offline
Hoopy frood
Joined: Feb 2004
Posts: 2,019
I don't really understand what the problem is here... just loop from back to front, easy as pie.

/*

Usage:

/reverseread <filepath>

Examples:

/reverseread versions.txt
/reverseread c:\my files\test.txt

*/

Code:
alias reverseread {
  var %file = $shortfn($$1-), %win = @win $+ $ticks
  if (!$isfile(%file)) return
  window -h %win
  loadbuf %win %file
  var %i = $line(%win,0)
  while (%i) { echo -a $line(%win,%i)  | dec %i }
  close -@ @@
}

I put that ^O char there after the $line(@@,%i) identifier, so that it would echo blank lines when encountered.

Joined: Sep 2003
Posts: 4,230
D
Hoopy frood
Offline
Hoopy frood
D
Joined: Sep 2003
Posts: 4,230
Quote:
Ah my bad, asked whether there was a way to do it without the numbers in the start of the lines, but obviously cant for rotation.


They could be removed afterwards, however the time delay in doing so is quite large, far larger than i considered worth the effort, if you know there there you can as i have shown just deal with them.

Joined: Oct 2005
Posts: 16
S
saxorr Offline OP
Pikka bird
OP Offline
Pikka bird
S
Joined: Oct 2005
Posts: 16
Hmm it seems I'm gonna need more help with this one..

DaveC your idea works like a charm, except the file it reads from is 5.5mb big and it has 70,000 lines (and growing as we speak), it takes quite a while for the filter commands to take place to recreate the file...but it'll definetly be my option if I dont find a better way.

FiberOPtics, with your command (or anyone else who understands how his command works), is there a way to search for something as oppose to just echo'ing the file from bottom to top? Eg someone can go

!search xx

Then with your /reverseread it'll search for the 2nd word starting from the bottom, to the top.

Thanks again

Joined: Feb 2004
Posts: 2,019
Hoopy frood
Offline
Hoopy frood
Joined: Feb 2004
Posts: 2,019
What you should have done from the start, and which is a common mistake that people do when asking for help here, is to explain the framework that the code is supposed to work in.

Quote:
except the file it reads from is 5.5mb big and it has 70,000 lines (and growing as we speak),

Why do you only mention this now? You should have mentioned that in your first post, as it is important if you want to be helped quickly with a good solution.

This is the same as with that internet pings thread. The guy started asking a very specific question about how to use icmp.dll in mIRC, and alllll the way at the bottom, I ended up giving him a 3 line solution that does exactly what he wants to do, but isn't related to icmp.dll at all.

Why exactly does it have to start looking from the back to the front btw? Does that have any particular reason? Maybe we can change something to your current setup so that we can read from the start to the end... but we can't unless you give us some more information about all of this.

Anyway, enough with the rambling:

To search for a word in a file, and to have access to them, you can filter the file. Example:

//window -h @@ | filter -fwc myfile.txt @@ *my string* | var %i = $line(@@,0) | while (%i) && (condition) { ... | dec %i } | close -@ @@

I'm not going to script it entirely for you, since you havent given enough information anyway. Try to make it yourself, you're never going to improve in anything if you have to depend on others all the time.

Note that since your file is already so big, and is growing, no solution using text files is going to cut it at some point. You're going to need to go with a hidden window or with hash tables, as using text files is far too inefficient.


Gone.
Joined: Oct 2005
Posts: 16
S
saxorr Offline OP
Pikka bird
OP Offline
Pikka bird
S
Joined: Oct 2005
Posts: 16
Thanks for the quick reply, and yes it's my mistake, but I thought there would of been an easy command added to the $read() command that wasn't listed on the mirc help file.

As for learning, yeah I appreciate learning commands, but you have to realise that the command you've given me are way out of my league, what I write are usually something stupid like

on *:text:xx:#: { /command } or /write or $read file

I've set my mirc so it captures the scores that another bot announces into a txt file, then people can go !search xx and it'll tell them the score for that game, I originally made it as

/write -il1 match.txt new score info here

-il1 makes a new line in the text file on every new entry, but the problem is the file has gotten too big (70,000 lines in a 5.5mb file) and it's starting to slowly kill my cpu everytime it pushes all the other lines to the bottom for the new one, so now I'm trying to prevent the problem early before it gets any worse..

Now I'm making it write the command as

/write match.txt new score info here

that way it places it in the bottom of the file and nothing needs alot of loading, the problem now is I need to search from the BOTTOM to the TOP because it's recording it in reverse order, and thats why I came here for help..

I'm not being lazy, I spend hours trying to write scripts and such and it's quite fun, but what you've given me is a complete diffrent language to me, no idea where to start...if you could help me with writing the whole script, that'll be appreciated, otherwise I'll wait and hope for someone else to help..

Joined: Sep 2003
Posts: 4,230
D
Hoopy frood
Offline
Hoopy frood
D
Joined: Sep 2003
Posts: 4,230
ok i have no idea how long 5.5mb at 70,000 lines takes to filter, im sure its gonna be to slow in real time. This might increase your chances of keeping up, ill explain it at the bottom.

Code:
alias match.txt.hidden.window {
  var %win = @match.txt.hidden.window
  if (!$window(%win)) {
    window -hn %win
    filter -fwcn MATCH.TXT %win
    filter -wwceut 1 32 %win %win
  }
  return %win
}
alias write.to.match.txt {
  if ($0) {
    iline $match.txt.hidden.window 1 $calc($line($match.txt.hidden.window,0) + 1) $1-
    write MATCH.TXT $1-
  }
}
;
; Code snipt follows to show a sweep from the bottom to the top of the file
{
  var %i = 1
  while ($fline($match.txt.hidden.window,&amp; *bob*,%i)) {
    var %line = $line($match.txt.hidden.window,$v1)
    var %original.line.number = $gettok(%line,1,32)
    var %original.line.text    = $gettok(%line,2-,32)
    echo -a line number %original.line.number contents %original.line.text
    inc %i
  }
}

* code is untested

When you have something to add to the MATCH.TXT file you add it by using /write.to.match.txt <what ever you want to add here> (simply your replacing the /write)
When you run this it well insert a line at line 1 to a hidden window (this window has the contents of MATCH.TXT in it,backwards with the original line numbers at the front of each line much like my resulting file from before)
it well write onto this new line a new line number and the contents of the line, and then also write the data to the MATCH.TXT file.

You can then use $fline($match.txt.hidden.window,& <yourmatchtext>,N) to isolate the matching line from the top down of the window, but matching the bopttom up of the file.
Remember the leading "& " to take care of the line numbers on the line smile
[see code snipit]


You might be looking at what $match.txt.hidden.window is, well it serves two functions, the first is to return the name of the hidden window @match.txt.hidden.window the second is the creating and loading of this window if it doesnt exist (this way you dont need to check for its existence and load it etc yourself, it well just exist when refrenced!) If it doesnt exist there well be a delay as its created, and then has the MATCH.TXT file filtered into it with line numbers, and then is reversed. But after that it should be resonablly quick. IF somehow you deleted the window, the next refrence of it using $match.txt.hidden.window, simply recreates it.

Joined: Oct 2005
Posts: 1,741
G
Hoopy frood
Offline
Hoopy frood
G
Joined: Oct 2005
Posts: 1,741
I haven't read the requirements of this request in detail, so this suggestion might be completely wrong..

If this event (reading 70000 line text file) needs to happen often and quickly, wouldn't it be better, or at least faster, to load the entire file into a hash table on START? The $hfind().data command could be used to search for entries in the hash table data entries.

Another thought is to trim the text file every so often. I don't know what the statistics actually are, but maybe its possible that the first 50000 entries are so old that they are irrelevant. Having 70000 lines seems a bit excessive to me. Maybe the ctime stamp could be added to the lines so that lines older than a few days/weeks could be purged.

If the code is recording current scores (points, frags, whatever) in a game, then why not store the information based on the name used in the game.
Example: /hadd scorehash $+(nick.,$1) $+($2,:,$3,:,$5,:,$8)
(Assuming that $1 was the player's game nick, and $2,$3,$5,$8 were important statistics.) Then when someone requests stats on a specific player, the result from a $hget(scorehash,$+(nick.,$1)) could be parsed into an informative message.

-genius_at_work


Link Copied to Clipboard