This is the new home of the egghelp.org community forum.
All data has been migrated (including user logins/passwords) to a new phpBB version.


For more information, see this announcement post. Click the X in the top right-corner of this box to dismiss this message.

read,extract and count >txt file in TCL

Help for those learning Tcl or writing their own scripts.
Post Reply
p
passion
Voice
Posts: 3
Joined: Mon Apr 26, 2010 7:48 pm

read,extract and count >txt file in TCL

Post by passion »

Hello folks,
I am quite new to TCL and seeking help from you guys to complete the following task. Thank you
I have to Search for the files with only .txt format in the current directory, count the number of cases of each different "Interface # nnnn" string in .txt file, where nnnn is a four or 32 digits max hexadecimal no and o/p of a table of Interface number against occurrence. I am facing implementation issues while writing a script i.e, Unable to implement the data structure like Linked List, Two Dimensional array. I am rewriting a script using multi dimension array (Pass values into the arrays in and out of procedure) in TCL to scan through the every .txt file and search for the the string/regular expression ‘Interface # ’ to count and display the number of occurrences. If someone could help me to complete this part will be much appreciated.
Here is my piece of code for searching a .txt file in present directory
Code:

Code: Select all

set files [glob *.txt]
if { [llength $files] > 0 } {
    puts "Files:"
    foreach f [lsort $files] {
        puts "    [file size $f] - $f"
    }
} else {
    puts "(no files)"
}
I reckon these are all the possible logical steps behind to complete it i) Once searched and find the .txt file then open all .txt files in read only mode ii) Create a array or list using the procedure (proc) Interface number to NULL and Interface count to zero 0 iii) Scan thro the .txt file and search for the string or regular expression "interface # iv) When a match found in .txt file, check the Interface Number and increment the count for the corresponding entry. Else add new element to the Interface Number list v) If there are no files return to the first directory

My o/p is like follows

Code: Select all

Code:
Interface    Frequency
123f            3
1232          4
User avatar
arfer
Master
Posts: 436
Joined: Fri Nov 26, 2004 8:45 pm
Location: Manchester, UK

Post by arfer »

It isn't clear whether this is a core Tcl project or something written for an Eggdrop bot, nevertheless I've provided an Eggdrop IRC public command !interface in the script below together with suitable output statements so that I can test it.

No directory/path is provided with the GLOB, FILE and OPEN commands, hence they default to the bots root directory.

The script searches all .txt files for the text 'interface xxxx' without regard to case, where xxxx is a four digit hexadecimal number.

Interface details are held in an array named iarray, where each array element name is the four digit hexadecimal number and the corresponding array element value is the frequency it occurs in the .txt files.

Code: Select all

# interface.tcl

bind PUB n !interface pPubCommand

proc pPubCommand {nick uhost hand channel txt} {
    if {[llength [split [string trim $txt]]] == 0} {
        pInterface
        pOutput $channel
    } else {putserv "PRIVMSG $channel :correct syntax is !interface without additional arguments"}
    return 0
}

proc pInterface {} {
    global flist iarray
    unset -nocomplain iarray
    set flist [lsort [glob -nocomplain -- *.txt]]
    foreach item $flist {
        set fp [open $item r]
        set fdata [read $fp]
        close $fp
        while {[regexp -nocase -- {interface ([0-9a-f]{4})} $fdata -> found]} {
            set fdata [regsub -nocase -- $found $fdata ""]
            set found [string tolower $found]
            if {[info exists iarray($found)]} {incr iarray($found)} else {set iarray($found) 1}
        }
    }
    return 0
}

proc pOutput {channel} {
    global flist iarray
    putserv "PRIVMSG $channel :\037files\037"
    if {[llength $flist] != 0} {
        foreach item $flist {
            putserv "PRIVMSG $channel :$item [file size $item] bytes"
        }
        putserv "PRIVMSG $channel :\037interfaces\037"
        if {[array size iarray] != 0} {
            foreach item [lsort [array names iarray]] {
                putserv "PRIVMSG $channel :interface $item frequency $iarray($item)"
            }
        } else {putserv "PRIVMSG $channel :no interfaces found"}
    } else {putserv "PRIVMSG $channel :no files found"}
    return 0
}
This is the original output (there are .txt files in the bot's root directory, but no text that matches the regular expression) :-

[09:54] <@arfer> !interface
[09:54] <@osmosis> files
[09:54] <@osmosis> abuseat.txt 252 bytes
[09:54] <@osmosis> access.txt 12076 bytes
[09:54] <@osmosis> chanstats.txt 53 bytes
[09:54] <@osmosis> url.txt 0 bytes
[09:54] <@osmosis> interfaces
[09:54] <@osmosis> no interfaces found

I created two .txt files in the bot's root directory as follows :-

test1.txt
this is a test
my Interface ac67 and my interface 458A
did i say InterFace AC67?

test2.txt
interface 432b
Interface 675c and InterfaCE AAAb
i think i said interface 458a in test1.txt
try 3 times ... interface bbb4, INTERFACE BBB4, inTERface bBb4

This is the script output after creating the two files :-

[10:13] <@arfer> !interface
[10:13] <@osmosis> files
[10:13] <@osmosis> abuseat.txt 252 bytes
[10:13] <@osmosis> access.txt 12076 bytes
[10:13] <@osmosis> chanstats.txt 53 bytes
[10:13] <@osmosis> status.txt 371 bytes
[10:13] <@osmosis> test1.txt 84 bytes
[10:13] <@osmosis> test2.txt 159 bytes
[10:13] <@osmosis> url.txt 0 bytes
[10:13] <@osmosis> interfaces
[10:13] <@osmosis> interface 432b frequency 1
[10:13] <@osmosis> interface 458a frequency 2
[10:13] <@osmosis> interface 675c frequency 1
[10:13] <@osmosis> interface aaab frequency 1
[10:13] <@osmosis> interface ac67 frequency 2
[10:13] <@osmosis> interface bbb4 frequency 3
I must have had nothing to do
Post Reply