#!/bin/sh # \ exec tclsh "$0" ${1+"$@"} namespace eval xtcl {} proc xtcl::usage {} { set s [info script] return "Usages: $s ?-debug? -line tcl_command Iterate through each line in each file found and call the script $s -file tcl_command Iterate through each line in each file found and $s -match Finds files and prints out filenames : -find glob_pattern -since -files ?file1 ?file2? ?..?? " } proc xtcl::showUsage {} { puts stderr [xtcl::usage] exit 1 } # # file matching # proc xtcl::matchFiles {argv} { switch -glob -- [lindex $argv 0] { -f - -fi - -fil - -file - -files { return [lrange $argv 1 end] } -exec { set rc [list] if {[catch [concat [list exec --] [lrange $argv 1 end]] filelist]} { return -code error $filelist } foreach line [split $filelist \r\n] { if {$line != ""} { lappend rc $line } } return $rc } -* { showUsage } } return $argv } proc xtcl::foreachFile {filelist body} { # some standard variables upvar 1 contents contents filename filename filenumber filenumber set filenumber 0 foreach filename $filelist { incr filenumber set fh [open $filename r] set origcontents [read $fh] close $fh set contents $origcontents uplevel 1 $body if {![string equal $origcontents $contents]} { set fh [open $filename w] puts -nonewline $fh $contents close $fh } } } # # main code # # match global flags while {[llength $argv] > 0} { switch -- [lindex $argv 0] { -to { set xtcl::toDirectory [lindex $argv 1] set argv [lrange $argv 2 end] incr argc -2 continue } default { break } } } # if we don't have any mode, throw the usage if {[llength $argv] == 0} { xtcl::showUsage } # match usage mode switch -- [lindex $argv 0] { -m - -ma - -mat - -matc - -match { # find files matching the criteria set files [xtcl::matchFiles [lrange $argv 1 end]] puts [join $files \n] exit 0 } -l - -li - -lin - -line { set command [lindex $argv 1] set files [xtcl::matchFiles [lrange $argv 2 end]] xtcl::foreachFile $files { set newcontents [list] set linenumber 0 foreach line [split $contents \n] { incr linenumber eval $command lappend newcontents $line } set contents [join $newcontents \n] } } -f - -fi - -fil - -file { set command [lindex $argv 1] set files [xtcl::matchFiles [lrange $argv 2 end]] xtcl::foreachfile contents $files { eval $command } } default { xtcl::showUsage } } exit 0