There are many simple example scripts that every Tcl/Tk programmer should keep around for reference. They are good examples of Tcl/Tk techniques, and they're just plain handy sometimes. (Thanks to Harald Kirsch for suggesting the collection on comp.lang.tcl) Also think about The RC File.

LV: today I am only partially able to access the internet - it would be useful for someone with full access to look through the following list and submit Feature Requests to http://tcllib.sf.net/ to get some of this great code into a tcllib distribution.

Doing a full sed replacement is hard. It is better to just write a Tcl program/procedure from scratch that implements the functionality. This is probably easier though if someone implements some kind of line iterator (suitable for most simple uses of sed where all you want to do is apply a substitution to each line of a file/stream or only print some lines.) It is probably easier to just run sed externally (with [exec]) for anything that is very complex and where you've not the time to reimplement.

However, as a little goodie, here are some alternatives to very common sed commands...

This is actually one of the simplest Unix utilities, but even so I will only produce a cut-down version here. The only option I support is -c (to precede each line by the number of times in sequence it occurs.)

The following implementation of tr shows how [string map] can be used to transliterate characters. A production implementation would probably maintain a cache of the translation list going into [string map], but this implementation gives the basics. Note that the implementation didn't need to do anything special to be Unicode-aware; you can, for instance, use it to substitute Katakana for Hiragana by doing [tr \u3041-\u309e \u30a1-\u30fe $japaneseString]

This proc will bind a new event to ".". It can show you when mouse events occur, if you bind it to things like Enter or Motion.

proc unk {e} {bind . <$e> "puts $e"}

If you have an event driven program, end it with tclx mainloop.

Then you can

tcl> source program.tcl

(churnchurnchurn)

tcl>

You have an event driven command prompt while the program is running. You can dump arrays, invoke routines, run profile, all sorts of things. Mainloop is smart enough so that when you run it stand-alone

tcl program.tcl

It does the right thing.

May all your programs be event driven.

DKF: Note that people running wish on Unix platforms can simply use [send] as a way to attach a console to a running Tcl/Tk program. The distributed demo script, rmt does this, (and is perfectly adequate for a lot use), or you could use Jeff Hobbs's tkcon which is more sophisticated.

JDG: If you want a very simple command line, you can also use the interp.tcl script for the plain-text interface to JStrack, which hasn't been touched for almost a decade. Download the JStrack source from jstrack.org and look in the tracker/lib directory. interp.tcl is there. This is part of JStrack (a very ancient part, I might add), and was originally provided by Jeff Hobbs, with a lot of help from Brent Welch (et al) in expanding it. Just source it as the *LAST* line in your script.

JDG 2010-06-25: FWIW, I now use Jeff Hobbs's tkcon.tcl and the tkcon_wrap.tcl ... and really need to update JStrack to use these, as well.

If (in tcl 8.1 or above) tcl has misinterpreted the charset of some string gotten from an external program or system function, and you are left with a string with Latin-1 accented characters (\u0080-\u00FF) instead of your language letters, you can fix the string using

Volker: The beauty of scripting lies (a.o.) in the fact that you can have lots of little programs cooperating with each other. For this, a simple means of communication is necessary. This simple server (and even simpler client) show how it works:

The server above is good enough for single line requests. It handles all the interaction between gets, eof and fileevent correctly (IMHO) and can certainly serve several connections at once. It can cope with clients closing their sockets at any time.

If you don't specify the port number explicitly (2000 in this case), but specify 0, the socket finds the first free port. You can then ask the handle for its port number and try to get it to your clients. for instance by writing it into a file or something.

The client demonstrates that the server does indeed accumulate a complete line first, before it gets processed. the magic behavior of gets is largely responsible for that, which makes the server so simple.

Well, that's it! :-)

Pelle Otterholm: Here is another version of the server part that you might want to use.

"Returns 1 if an end of file condition occurred during the most recent input operation on channelId (such as gets), 0 otherwise."

Also, the return value of [gets] should be checked so that you can differentiate between receiving a blank line and having an error or end-of-file. Two-argument [gets] will return -1 on error and end-of-file (use [eof] to tell the difference), 0 on blank line or no-data-available (when the channel is nonblocking; use [fblocked] to test this).

Pelle Otterholm: the code is based on same coding idea as Simple TCP/IP proxy, also changed to line buffering and move gets $fd file into the check, getting : "if {!([eof $fd] || [catch {gets $fd}]) }"