Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How to write output of a tcl script to a file?

6,369 views
Skip to first unread message

kj

unread,
Nov 13, 2008, 2:23:44 AM11/13/08
to
Hi All

I am a newbie in Tcl. And when it comes to file I/O, I get extremely
confused.
I am trying out below example from Tcl tutorial
(Link ---> http://www.tcl.tk/man/tcl8.5/tutorial/Tcl25.html )

#
# Report all the files and subdirectories in the current directory
# For files: show the size
# For directories: show that they _are_ directories
#

set dirs [glob -nocomplain -type d *]
if { $dirs != {} } {
puts "Directories:
foreach d [lsort $dirs] {
puts " $d"
}
} else {
puts "(no subdirectories)"
}

set files [glob -nocomplain -type f *]
if { $files != {} } {
puts "Files:
foreach f [lsort $files] {
puts " [file size $f] - $f"
}
} else {
puts "(no files)"
}
################################

I want to write the output of this script directly to the new file.
help me with that.

And if anyone can provide a good tutorial with lots of examples about
File I/O in Tcl, that'd be best.
thanks in advance.

Arjen Markus

unread,
Nov 13, 2008, 2:49:15 AM11/13/08
to

File I/O is pretty easy - you can see a lot of examples on the
Wiki (http://wiki.tcl.tk) - but I do not know of any tutorials
specific for this subject.

Here is some more information:

1. Tcl does not distinguish (at the script level!) between
files on disk or sockets or the console or ...
Use puts to write to any of them, use read and gets to
read from them.

1a. Sockets are a bit special, in that they usually require
an event loop for proper handling, but again, the Wiki
has plenty examples.

2. Open a file on disk with [open]. This command returns
a "handle" or identifier that you can pass to puts or
gets or read. (puts and gets also take an implicit
handle: "puts Aha" will be translated as it were to
"puts stdout Aha" - where stdout is a predefined
handle indicating the console or standard output.
"gets text" is translated to "gets stdin text":
read a line of text from the keyboard)

So, to write a list of files to a file called "aha",
it gets as simple as:

set outfile [open "aha" w]
puts $outfile [glob *]
close $outfile

Hope that helps,

Arjen

Dmitry Kobylin

unread,
Nov 13, 2008, 3:33:15 AM11/13/08
to
1) You can redirect output by:
./runnable_tcl_script > some_file


2) Using "dup" command from TclX package may be a solution
http://wiki.tcl.tk/1996
http://wiki.tcl.tk/207


code shoud look something like this:

package require Tclx

set fd [open /path/to/file w]
dup $fd stdout
puts "All this output shoud go to file"
close $fd

kj

unread,
Nov 13, 2008, 4:19:54 AM11/13/08
to

Done like a charm. Below is the code
#################################

set dirs [glob -nocomplain -type d *]

set outfile [open "abc.txt" w]
if { $dirs != {} } {
puts $outfile "Directories:
foreach d [lsort $dirs] {
puts $outfile " $d"
}
} else {

puts "(no subdirectories)"

}

set files [glob -nocomplain -type f *]
if { $files != {} } {

puts $outfile "Files:
foreach f [lsort $files] {
puts $outfile " [file size $f] - $f"
}
} else {

puts "(no files)"
}
close $outfile

################################

Thanks for the help.

Ralf Fassel

unread,
Nov 13, 2008, 4:36:47 AM11/13/08
to
* kj <kinjalde...@gmail.com>

| Done like a charm. Below is the code
| #################################
|
| set dirs [glob -nocomplain -type d *]
| set outfile [open "abc.txt" w]
| if { $dirs != {} } {

Tip: 'glob' returns a list, but by comparing the list to the empty
string here, TCL converts the list to a string first, which can be a
performance hit on large directories. You can skip this conversion if
you check the list length instead:

if { [llength $dirs] > 0 } {

| foreach d [lsort $dirs] {

Usually when it comes to file names, the more 'natural' sort is

foreach d [lsort -dictionary $dirs]

Compare:
lsort {file1 file2 file10}
=> file1 file10 file2

lsort -dictionary {file1 file2 file10}
=> file1 file2 file10

HTH
R'

Donal K. Fellows

unread,
Nov 13, 2008, 4:38:21 AM11/13/08
to
Dmitry Kobylin wrote:
> 1) You can redirect output by:
>    ./runnable_tcl_script > some_file

You can also do this inside the script:

close stdout; open some_file w

Be aware that if this goes wrong, you can't recover without exiting
the script.

Donal.

Cameron Laird

unread,
Nov 14, 2008, 11:33:16 AM11/14/08
to
In article <729802e3-dadd-46fd...@f40g2000pri.googlegroups.com>,
Arjen Markus <arjen....@wldelft.nl> wrote:
.
.
.

>1. Tcl does not distinguish (at the script level!) between
> files on disk or sockets or the console or ...
> Use puts to write to any of them, use read and gets to
> read from them.
>
>1a. Sockets are a bit special, in that they usually require
> an event loop for proper handling, but again, the Wiki
> has plenty examples.
.
.
.
Your 1a intrigues me, Arjen. If you'd written, "they often require
..." or "they often are best handled with ...", I'd be fine. I'm
stumbling over the thought that they *usually require* asynchronous
handling, though. Perhaps the distinction is just that, while I
recognize the standard ftp.tcl, http.tcl, smtp.tcl, ... are implemented
with non-blocking, asynchronous sockets, I don't see these as
*necessary*, because there certainly are plenty of useful networking
tools bearing on these protocols which simply block.

Arjen Markus

unread,
Nov 17, 2008, 4:10:18 AM11/17/08
to
On 14 nov, 17:33, cla...@lairds.us (Cameron Laird) wrote:
> In article <729802e3-dadd-46fd-b69c-8781d4cfb...@f40g2000pri.googlegroups.com>,

I do not think my answer was meant to be very profound. I was
merely thinking of my own experience with them.

Regards,

Arjen

0 new messages