Pages

Saturday, February 18, 2012

TCL-1

How TCL works..
Advantage : keep all the commands in same file and execute.
We can over-write the existing procedure with our own
In tcl interpretor collects the commands along with arguments and trigger the procedure already written in C for execution.

Two ways of execution :
1. chmod u+x test.tcl  followed by ./test.tcl  here we are making the file executable
2. tclsh test.tcl ...no need to make the file executable since we are in tcl shell.

Tcl is also called as positional based language since same parameter like "\" behave diffrently when used as backslash and line continuation .

 After TCL installed on the¯ machine, TCL information got  registred in the machine.
e.g:In Windows Registry
[HKEY_LOCAL_MACHINE\SOFTWARE\ActiveState\ActiveTcl]

The TCL path is updated in Machine environment.
e.g:
PATH=C:/Tcl/bin;%PATH%

Then TCL starts working.

TCL is a Scripting Language. TCL binary comes with  name "tclsh".
When we use TCL,[ For example from Command prompt/Terminal  try to run tclsh ] it provides default prompt "%" to User  and asks for input.
#tclsh
%

Each input from user is treated as TCL command. After providing the command, tclsh fetch(gets) that command  and try to validate/compile/execute and populate(puts) the  message.

#tclsh
% hello
invalid command name "hello"
% set
wrong # args: should be "set varName ?newValue?"
%set say "Hello"
Hello

When we use TCL, we can provide a Script file as  argument.
Example: Create a file "HelloTickle.tcl" containing:

How to increment each element in a list.set list {1 2 3}regsub -all {(\d+)} $list "\[expr \\1 + 1\]" new_listputs $new_listset result [eval concat "" $new_list]puts $resultoutput:
[expr 1 + 1] [expr 2 + 1] [expr 3 + 1]
2 3 4

How to run  a package in tcl
source
(or)
package require

How to increment a char?
set ch a
set n [scan $ch %c]
incr n
set m [format %c $n]
puts "$m"

How to Swap 30 & 40 in IP address 192.30.40.1 using TCL script?
There can be done in several ways:
set a 192.30.40.1
set b [ string range $a 3 4 ]
set c [ string range $a 6 7 ]
set d [ string replace $a 3 4 $c ]
set e [ string replace $d 6 7 $b]
puts $e
or
 set a 192.30.40.1
set b [ split $a .]
set u [lindex $b 0]
set v [lindex $b 3]
set x [lindex $b 1]
set y [lindex $b 2]
set z [join "$u $y $x $v" .]
puts $z
or
set ip 192.30.40.1
regexp {([0-9]+\.)([0-9]+\.)([0-9]+\.)([0-9]+)} $ip match 1st 2nd 3rd 4th
append new_ip $1st $3rd $2nd $4th
puts $new_ip
 or
set x 192.30.40.1
set srcStr {([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)}
regexp  $srcStr $x - d1 d2 d3 d4
regsub $srcStr $x  "$d1.$d3.$d2.$d1" x
puts $x
 or
set a 192.30.40.1
puts "Before swaping a: $a"
set a [split $a .]
set a [join "[lindex $a 0] [lindex $a 2] [lindex $a 1] [lindex $a 3]" .]
puts "After swaping a: $a"
or
set ip 192.30.40.1
set sp [split $ip "."]
set l [lindex $sp 1]
set m [lindex $sp 2]
set n [lreplace $sp 1 2 $m $l]
set sip [join $n "."]
puts "$sip"

How to extract "information" from
"ccccccccaaabbbbaaaabbinformationabcaaaaaabbbbbbbccbb" in tcl using a single command?
set a "ccccccccaaabbbbaaaabbinformationabcaaaaaabbbbbbbccbb"
set b [string trimleft $a "abc"]
puts $b
set c [string trimright $b "abc"]
puts information
 or
 set a "ccccccccaaabbbbaaaabbinformationabcaaaaaabbbbbbbccbb"
set output [string trimright [string trimleft $a "abc"] "abc"]
puts $output

How do you find the length of a string without using string length command in TCL?
set str "lenghtofthisstring"
set list1 [ split $str "" ]
foreach value $list1 {
incr len
}
puts $len

string first a 0a23456789abcdef 5 will return 10

string first a 0123456789abcdef 11 will return -1
to get 2nd last charcetr in string
set H "hello"
string index $H end-1 or end-2 or end-3
string last a 0a23456789abcdef 15 will return 10 but
string last a 0a23456789abcdef 9 will return 1

set h "nawraj"
string repeat $h 3

string map {abc 1 ab 2 a 3 1 0} 1abcaababcabababc
will return the string 01321221

{}
ab
abab
ababab
regexp for above is {ab}* = 0 or more of ab
if null string is not present the {ab}+ == one or more of ab

{}
3
4
regexp is {\d}?

File modes :
r  == Open the file for reading only; the file must already exist. This is the default value if access is not specified.
r+ == Open the file for both reading and writing; the file must already exist.

w == Open the file for writing only. Truncate it if it exists. If it doesn't exist, create a new file.
w+ == Open the file for reading and writing. Truncate it if it exists. If it doesn't exist, create a new file.

a  == Open the file for writing only. The file must already exist, and the file is positioned so that new data is appended to the file.
a+ == Open the file for reading and writing. If the file doesn't exist, create a new empty file. Set the initial access position to the end of the file.

In tcl , by default stdout is output channel id.

Read :
 set fp [open "somefile" r]
 set file_data [read $fp]
 close $fp

 set fp [open "somefile" r+]
 set file_data [read $fp]
 set data "hello how r u"
 puts -no newline $fp $data
 close $fp
Now if u open a file ..vi somefile ..hello how r u will be added

Write:
# create some data
set data "This is some test data.\n"
# pick a filename - if you don't include a path,
#  it will be saved in the current directory
set filename "test.txt"
# open the filename for writing
set fileId [open $filename "w"]
# send the data to the file -
#  failure to add '-nonewline' will result in an extra newline
# at the end of the file
puts -nonewline $fileId $data
# close the file, ensuring the data is written out before you continue
#  with processing.
close $fileId

File Handling
As in all other good languages, Tcl also can open, read and write to files. And like all other good tutorials, this tutorial also teaches how to do it. First let us see how to open a file.
open
Syntax:
open fileName ?access? ?permissions?

fileName is the name of the file. The access argument, if present, specifies the way in which the file should be accessed. It can have any of the following values:
r    Open the file for reading only; the file must already exist. This is the default value if access is not specified.
r+    Open the file for both reading and writing; the file must already exist.
w    Open the file for writing only. If there is a file by that name, then delete all the contents of the file. If it doesn't exist, create a new file.
w+    Open the file for reading and writing. If there is a file by that name, then delete all the contents of the file. If it doesn't exist, create a new file.
a    Open the file for writing only. If the file doesn't exist, create a new empty file. Set the initial access position to the end of the file.
a+    Open the file for reading and writing. If the file doesn't exist, create a new empty file. Set the initial access position to the end of the file.
null see an example.

#Open the file called "jokes.txt" for writing
open "jokes.txt" w

Now we know how to open a file. Not much good, is it? To make this function useful, we need to write to the file.
puts
Syntax:
puts ?-nonewline? ?channelId? string

Use the -nonewline option only if you don't need a new line at the end of the string you write to a file. The channelID stands for the ID of the output stream that must be written to(if you don't understand what the means, don't worry. You will get it later.) string is the string you want to write to the file. Let's see the example.

#Open the file called "jokes.txt" for writing
set out [open "jokes.txt" w]
puts $out "Computers make very fast, very accurate mistakes."

Notice that I created a variable called 'out'. That will store the ID of the opened file. Always open a file in this way - otherwise they won't be of much use. Then we use that ID to write to the file using the command 'puts'. Now the file called "jokes.txt" has one line. Next, we have to close the file.
close
Syntax:
close ?channelId?

This command closes the channel. Always do this - else you will cry later. Let's move on to the ever-growing example...

#Open the file called "jokes.txt" for writing
set out [open "jokes.txt" w]
puts $out "Computers make very fast, very accurate mistakes."
close $out

After we close the file, we decide that we have to put more lines in the file. So now we open the file again, this time in the append mode. The example grows even longer...

#Open the file called "jokes.txt" for writing
set out [open "jokes.txt" w]
puts $out "Computers make very fast, very accurate mistakes."
close $out
set out [open "jokes.txt" a]
puts $out "Computers are not intelligent. They only think they are."
puts $out "My software never has bugs. It just develops random features."
puts $out {All computers wait at the same speed.
Best file compression around:  "DEL *.*" = 100% compression
DEFINITION: Computer - A device designed to speed and automate errors.
DEFINITION: Upgrade - Take old bugs out, put new ones in.}
close $out

After we have done that, we need to read the jokes and put them back on the screen. So we learn a new command. Ladies and Gentlemen let me introduce you to...
gets
Syntax:
gets channelId ?varName?

gets will copy one line from the channel(or file) and put it in varName. If varName is not specified, the copied line will be the result of the function. We go back to our example and get the first line of the file. For that we open the file again, this time in read mode.

#Open the file called "jokes.txt" for writing
set out [open "jokes.txt" w]
puts $out "Computers make very fast, very accurate mistakes."
close $out
#Now append more jokes at the end of the file
set out [open "jokes.txt" a]
puts $out "Computers are not intelligent. They only think they are."
puts $out "My software never has bugs. It just develops random features."
puts $out {All computers wait at the same speed.
Best file compression around:  "DEL *.*" = 100% compression
DEFINITION: Computer - A device designed to speed and automate errors.
DEFINITION: Upgrade - Take old bugs out, put new ones in.}
close $out
#Opening file in read mode
set in [open "jokes.txt" r]
gets $in line
label .line -text "First Line : $line"
pack .line

This command can be used to read the whole file line by line. See the example below to see how. Don't worry about .txt insert end "$line\n---\n" - I will explain it later.

text .txt
set in [open "Jokes.txt" r]
while {[gets $in line] != -1} {
    #Do whatever you want with the $line variable
    .txt insert end "$line\n---\n"
}
close $in
pack .txt -expand 1 -fill both

This command is for reading the file line by line. Now we decide that we need to see the entire file. For that, we need the read command. But remember that if we have read one line before
seek
Syntax:
seek channelId offset ?origin?

The offset and origin arguments specify the position at which the next read or write will occur for channelId. The offset must be an integer (which may be negative) and origin must be one of the following - start, current or end.

Now we have to read the file contents. So we move on to...
read
Syntax:
read channelId ?numChars?

read will take numChars characters from the channel and return it. If numChars is not specified, the whole file is read and its content will be returned. You can read a file and then get all the lines into a list with every line as an item in the list. This can be done by...

set in [open "file.txt" r]
set contents [read $in]
close $in
set lines [split $contents "\n"]

Now every item in the list called $lines is a line of the file called "file.txt". On to the example - for the last time.

#Open the file called "jokes.txt" for writing
set out [open "jokes.txt" w]
puts $out "Computers make very fast, very accurate mistakes."
close $out
#Now append more jokes at the end of the file
set out [open "jokes.txt" a]
puts $out "Computers are not intelligent. They only think they are."
puts $out "My software never has bugs. It just develops random features."
puts $out {All computers wait at the same speed.
Best file compression around:  "DEL *.*" = 100% compression
DEFINITION: Computer - A device designed to speed and automate errors.
DEFINITION: Upgrade - Take old bugs out, put new ones in.}
close $out
#Opening file in read mode
set in [open "jokes.txt" r]
gets $in line
label .line -text "First Line : $line"
pack .line
seek $in 0 start
set contents [read $in]
close $in
label .full -text "Full file Contents... \n$contents"
pack .full

There. That's about it with file handling.
-------------------------
How do I read and write files in Tcl
One way to get file data in Tcl is to 'slurp' up the file into a text variable. This works really well if the files are known to be small.
     #  Slurp up the data file
     set fp [open "somefile" r]
     set file_data [read $fp]
     close $fp
Now you can split file_data into lines, and process it to your heart's content. NOTE: The mention of split is important here- input data is seldom well-behaved/structured, and needs to be processed in this way to ensure that any potential Tcl metacharacters are appropriately quoted into list format.
     #  Process data file
     set data [split $file_data "\n"]
     foreach line $data {
          # do some line processing here
     }

#  read the file one line at a time
     set fp [open "somefile" r]
     while { [gets $fp data] >= 0 } {
          puts $data
     }
     close $fp

Writing a file
# create some data
        set data "This is some test data.\n"
        # pick a filename - if you don't include a path,
        #  it will be saved in the current directory
         set filename "test.txt"
        # open the filename for writing
         set fileId [open $filename "w"]
        # send the data to the file -
        #  failure to add '-nonewline' will result in an extra newline
        # at the end of the file
        puts -nonewline $fileId $data
        # close the file, ensuring the data is written out before you continue
        #  with processing.
        close $fileId







No comments:

Post a Comment