Richard Suchenwirth 2011-08-14 - After a long time, here's a little weekend fun project again: a tool with which to search a text file. Call it like
vgrep.tcl myfile.txt &
and get a window with an entry, into which a query can be typed, and a scrolled text widget which displays the matching lines.
The query is processed at each key press, independent of case, and with .* substituted for blanks, so
the bat
matches both
TheBat_1929.mp4;... the_batmobile_1988.ogv;...
The number of hits is displayed in the title bar. I needed this thingy to search my film collection, and it performs reasonably well with a file of some 6500 lines on a netbook.
Screenshot using vgrep on itself...
#!/usr/bin/env tclsh set usage { usage: vgrep textfile & Show the given textfile. If strings are entered into the top entry widget, filter only those lines that match (case-indepent, spaces mean .*) } if {[llength $argv] != 1} {puts stderr $usage; exit 1} package require Tk proc main argv { set font {Arial 12} pack [entry .e -font $font] -fill x bind .e <KeyRelease> {rewrite .e .t} pack [scrollbar .y -command ".t yview"] -side right -fill y pack [text .t -wrap none -yscroll ".y set" -font $font] \ -fill both -side left -expand 1 .t tag configure blue -foreground blue set ::data [readlines [lindex $argv 0]] rewrite .e .t focus -force .e } proc rewrite {entry text} { global data $text delete 1.0 end set re [string map {" " .*} [$entry get]] foreach line $data { if {$re eq "" || [regexp -nocase $re $line]} { foreach {file path} [split $line ";"] break $text insert end $file black " ; $path\n" blue } } wm title . "[int [$text index end-2c]] hits - vgrep $::argv" } proc int x {expr {int($x)}} proc readlines filename { set f [open $filename] split [read -nonewline $f][close $f] \n } main $argv bind all <Escape> {exec tclsh $argv0 $argv &; exit}