[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.<
>
[vgrepSS]
<
>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 {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 {exec tclsh $argv0 $argv &; exit}
======
<>Category Example