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.
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
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
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.
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'
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.
I do not think my answer was meant to be very profound. I was
merely thinking of my own experience with them.
Regards,
Arjen