tcl指南

Tcl代表Tool Command Language。tcl是一种基于字符串的命令语言,这种语言只有几种基础结构和相对较少的语法,非常易于学习。

基础

hello word

1
2
3
4
#! /bin/tclsh
# this is comment
set var "hello world"
puts $var
1
hello world

puts 打印

set 赋值给变量

数学表达式

expr命令可以对数学表达式进行分析和计算。

1
puts [expr {7.2/4}]
1
1.8

{}和””

1
2
3
set s hello
puts "the length of $s is [string length $s]"
puts {the length of $s is [string length $s]}
1
2
the length of hello is 5
the length of $s is [string length $s]

使用“”会进行变量和命令替换,而{}替换被阻止。

过程proc

类似于函数功能。

1
2
3
4
5
proc add {a b} {
set c [expr $a + $b]
return $c
}
puts [add 3 4]
1
7

分组替换

命令变元以空格作为分隔符,除非它们被花括号或双引号包裹。这里比较容易出错的地方是}{之间如果没有空格就会报错。

1
2
3
proc add {a b}{
...
}

使用花括号{}进行分组会阻止替换。

使用双引号“”进行分组允许替换。

分组决定是在替换之前作出。意味着变量值或命令结果不影响分组。

美元符号$,会导致变量替换。

方括号[],会导致命令替换。

反斜杠\,用来引用特殊字符。

替换操作可以发生在任何地方,除非使用花括号加以阻止。

在调用命令之前只完成一遍替换,不再对替换结果进行第二遍解析。

字符串

字符串是Tcl中的基本数据。

命令 说明
string bytelength str 返回用于存储字符串的字节数,由于UTF8编码的原因,这个长度可能与string length返回长度不一样
string compare ?-nocase? ?-length len? Str1 str2 根据词典顺序比较两个字符串,nocase表示忽略大小写,length表示比较前n个字符,如果相同返回值为0,如果str1靠前就返回-1,对于其他情况返回1
string equal ? –nocase? Str1 str2 比较字符串,如果相同返回1,否则-1,使用nocase来表示忽略大小写
string first str1 str2 返回str2str1第一次出现的位置,如果没有的话,就返回-1
string is class ?-strict? ?-failindex varname? string 如果string属于某个class就返回,如果指定了strict,那么就不匹配空字符串,否则总是要匹配,如果指定了failindex,就会将在string中阻止其称为class一员的字符串索引赋给varname
string last str1 str2 返回str2str1最后一次出现的位置,如果没有出现就返回-1
string length str 返回string中的字符个数
string map ?-nocase? charMap string 返回一个根据charmap中输入输出列表将string中的字符进行映射后产生的字符串。
string match pattern str 如果str匹配pattern就返回1,否则返回0
string range str i j 返回字符串中从ij的部分。
string repeat str count 返回将str重复count次的字符串
string replace str first last ?newstr? 返回一个通过把从firstlast字符串替换为newstr的新字符串,或是返回空
string tolower string ?first? ?last? 返回string的小写形式,firstlast决定了字符串位置
string totitle string ?first? ?last? 将第一个字符替换为大写,其他为小写,firstlast决定了字符串位置
string toupper string ?first? ?last? 返回string的大写格式,firstlast决定了字符串位置
string trim string ?chars? string两端除去chars中指定的字符,chars默认空
string trimleft string ?chars? string的左端除去chars中指定的字符,chars默认为空
string trimright string ?chars? string的右端除去chars指定的字符,chars默认为空
string wordend str ix 返回str中在索引ix位置包含的字符的单词之后的字符的索引位置
string wordstart str ix 返回str中在索引ix位置包含字符串的单词中第一个字符的索引位置。

length

1
2
3
set name "hello"
string length $name
=> 5

compare and equal

1
2
3
4
5
6
if {[string compare $s1 $s2] == 0} {
# strings are equal
}
if {[string equal $s1 $s2]} {
# strings are equal
}

match

字符 说明
* 匹配任意数量的任意字符
? 确切地匹配一个字符
[chars] 匹配chars中的任意一个字符
1
2
3
4
5
6
7
8
9
string match a* alpha
=> 1

string match ?? xy
=> 1

set pat {[ab]*x}
string match $pat box
=> 1

format

和c语言printf一样

1
2
3
4
set name "hello"
set value 10
puts [format "name is %s, value is %d" $name $value]
=> name is hello, value is 10

列表

列表类似于数组的概念。

命令 说明
list arg1 arg2 根据所有的值构造一个列表
lindex list i 返回list的第i个元素
llength list 返回list的元素个数
lrange i j 返回list中从第i个到第j个的元素
lappend list arg1 arg2 将元素追加到list的后面
linsert list index arg 将元素追加到list中位于index之前的位置
lreplace list i j arg arg list中从ij的元素替换为args
lsearch ?mode? list value 根据mode(-exact –glob-regexp)返回list中与value匹配的元素索引,如果没有就返回-1
lsort ?switches? list 根据开关选项对list进行排序
concat list list 将多个list连接
join list joinstring joinstring为分隔符,将列表中的元素合并在一起
split string split chars 使用split chars中的字符串作为列表元素的分割
1
2
3
set new [list 1 2 3]
puts $new
=> 1 2 3

lappend

1
2
3
4
lappend new 1 2
=> 1 2
lappend new 3 "4 5"
=> 1 2 3 {4 5}

concat

concat命令和双引用的行为非常相似。concat命令会先取出其变元末尾的多余空白符,然后才使用一个单一空格将他们连接起来。

1
2
3
4
5
6
7
8
9
10
11
12
set x {4 5 6}
set y {2 3}
set z 1
concat $z $y $x
=> 1 2 3 4 5 6

set x {1 2}
set s { 2 }
set y [concat 1 $s 3]
=> 1 2 3
set z [list $x $s 3]
=> {1 2} { 2 } 3

获取列表元素

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
llength {a b {c d} "e f g" h}
=> 5
llength { }
=> 0

set x {1 2 3}
lindex $x 1
=> 2

# the last item
lindex $list [expr {[llength $list] -2}]
lindex $list end-1

# range
lrange {1 2 3 {4 5}} 2 end
=> 3 {4 5}

修改列表

1
2
3
4
5
6
7
8
linsert {1 2} 0 new stuff
=> new stuff 1 2
set x [list a {b c} e d]
=> a {b c} e d
lreplace $x 1 2 B C
=> a B C d
lreplace $x 0 0
=> {b c} e d

搜索列表

lsearch返回列表中一个值的索引,如果值不存在就返回-1。lsearch在搜索中支持模式匹配,默认为通配风格的模式匹配,可以使用-exact标志将其禁止。

1
2
lsearch {here is a list} l*
=> 3

使用命令lreplace和lsearch根据值来删除列表元素。

1
2
3
4
5
6
7
8
proc ldelete { list value } {
set ix [lsearch -exact $list $value]
if {$ix >= 0} {
return [lreplace $list $ix $ix]
} else {
return $list
}
}

排序

可以使用多种方式对列表进行排序。lsort不是对原表进行排序,而是返回一个新的列表。可以通过-ascii、-dictionary、-integer或-real选项指定排序类型,可以通过选项-increasing或-decreasing指定排序方式。默认的是-ascii -increasing。

1
2
3
4
lsort -ascii {a Z n2 n100}
=> Z a n100 n2
lsort -dictionary {a Z n2 n100}
=> a n2 n100 Z

分割

split默认分隔符是空白符,这包括空格符、制表符及换行符,如果一行有多个分隔符,就会产生空列表元素,分隔符并不合并。

1
2
3
set line "\thello, world."
split $line \ ,.\t
=> {} hello {} world {}

join

join与split相反。它接收一个列表值并使用指定的分隔列表元素的字符对其重新格式化。在处理过程中,它将删除列表的字符串表达中用来组织顶层元素的所有花括号

1
2
join {1 {2 3} {4 5 6}} :
=> 1:2 3:4 5 6

控制结构命令

if

1
2
3
4
5
6
7
if {$key < 0} {
incr range 1
} elseif {$key == 0} {
return $range
} else {
incr range -1
}

switch

switch flag value { pat1 body1 pat2 body2 …}

flag:

-exact 精确匹配,也是默认值

-glob 使用通配符的格式

-regexp 使用正则表达式匹配

没有标志(或者标志结束)。当value-开始的时候,必须用到这个。

1
2
3
4
5
6
7
8
9
10
11
switch -exact -- $value {
foo { doFoo; incr count(foo)}
default { incr count(other)}
}

set x [gets stdin]
switch -glob $x {
        *a* {puts "The word has alpha a"}
        *u* {puts "The word has alpha u"}
        default {puts "The word is error"}
}

while

1
2
3
4
while {$i<$x} {
set j [expr $j+$i]
incr i
}

for

1
2
3
for {set i 0} {$i<$x} {incr i} {
set j [expr $j+$i]
}

foreach

1
2
3
foreach value {1 3 2 11 5 4 7 6 9} {
puts $value
}

break continue

同大多数语言一样,break跳出循环,continue使循环进行下一次迭代。没有goto语句。

error

error message ?info? ?code?

过程与作用域

过程可以有默认参数。

1
2
3
4
5
6
proc P2 {a {b 7} {c -2} } {
expr $a / $b + $c
}

P2 6 3
=> 0

数组

set arr(index) value

命令 说明
array exist arr 如果arr是数组的话,就返回1
array get arr ?pattern 返回一个包含交替出现索引和对应数组值的列表,pattern是匹配索引,在没指定的情况下,匹配所有
array names arr? pattern 返回包含为arr定义的所有索引的列表,或是返回那些与字符串匹配模式pattern匹配的索引
array set arr list 根据list初始化数组
array size arr 返回为array定义的索引的数量
array startsearch arr 返回用于对array进行搜索的标记
array nextelement arr id 返回在记号id所标识的搜索中的数组的下一个元素的值,如果没有,就返回空
array anymore arr id 如果搜索中还有剩余的元素,就返回1
array donesearch arrid 结束由id标识的搜索
1
2
3
4
5
6
7
8
set list1 [list color1 red color2 yellow]
array set array1 $list1
puts [array exist array1]
=> 1
puts [array names array1]
=> color1 color2
puts [array size array1]
=> 2

附录

参考书籍《Tcl-TK编程权威指南》[点击下载]