TCL 笔记

1、lrange——列表操作

lrange - 返回列表中的一个或者多个临近的元素

语法

lrange list first last

描述

list必须是一个合法的列表。这个命令返回一个包含list中索引为firstlast的元素的列表,如果first小于0就被当作0来解释,如果last大于或者等于列表的长度,就被当作end来解释,如果first大于last返回空。

示例

选择列表的前两个元素:

% lrange {a b c d e} 0 1
a b

选择列表的后三个元素:

% lrange {a b c d e} end-2 end
c d e

选择除了第一个和最后一个其它所有的元素:

% lrange {a b c d e} 1 end-1
b c d

使用lrange选择一个单独的元素与lindex不同:

% set var {some {elements to} select}
some {elements to} select
% lindex $var 1
elements to
% lrange $var 1 1
{elements to}

 

 

2、dict——词典是用于值映射到键的布置。

常规字典的语法如下所示:

(1)dict set dictname key value
# or
dict create dictname key1 value1 key2 value2 .. keyn valuen
用于创建字典的一些例子如下所示:

#!/usr/bin/tclsh

dict set colours colour1 red
puts $colours
dict set colours colour2 green
puts $colours

set colours [dict create colour1 "black" colour2 "white"]
puts $colours
当执行上面的代码,产生以下结果:

colour1 red
colour1 red colour2 green
colour1 black colour2 white
(2)字典的大小
用于获取字典的大小语法如下所示:

[dict size dictname]
用于打印的尺寸一个例子如下所示:

#!/usr/bin/tclsh

set colours [dict create colour1 "black" colour2 "white"]
puts [dict size $colours]
当执行上面的代码,产生以下结果:

2
(3)字典迭代
打印键和字典的值一个简单的字典迭代如下所示:

#!/usr/bin/tclsh

set colours [dict create colour1 "black" colour2 "white"]
foreach item [dict keys $colours] {
set value [dict get $colours $item]
puts $value
}
当执行上面的代码,产生以下结果:

black
white
(4)字典的键值
字典键检索值的语法如下所示:

[dict get $dictname $keyname]
用于键检索值的示例如下面给出:

#!/usr/bin/tclsh

set colours [dict create colour1 "black" colour2 "white"]
set value [dict get $colours colour1]
puts $value
当执行上面的代码,产生以下结果:

black
(5)字典中的所有键
用于检索在字典的所有键的语法如下所示:

[dict keys $dictname]
用于打印所有的键一个例子如下所示:

#!/usr/bin/tclsh

set colours [dict create colour1 "black" colour2 "white"]
set keys [dict keys $colours]
puts $keys
当执行上面的代码,产生以下结果:

colour1 colour2
(6)字典中的所有值
用于检索在字典中的所有值的语法如下所示:

[dict values $dictname]
用于打印的所有值一个例子如下所示:

#!/usr/bin/tclsh

set colours [dict create colour1 "black" colour2 "white"]
set values [dict values $colours]
puts $values
当执行上面的代码,产生以下结果:

black white
(7)关键存在于字典
检查一个键是否存在于字典的语法如下所示:

[dict exists $dictname value]
用于检查一个键是否存在于字典的一个例子如下所示:

#!/usr/bin/tclsh

set colours [dict create colour1 "black" colour2 "white"]
set result [dict exists $colours colour1] #存在则返回1
puts $result
当执行上面的代码,产生以下结果:
1

 

More info: https://blog.csdn.net/asty9000/article/details/90217533

 

 

 

3、循环

for
for start test next body
for是一个与C语言中for结构类似的循环命令。start、next和body必须是Tcl命令字符串,test是表达式字符串。for命令首先调用Tcl解释器来执行start进行一些初始化操作。然后将test做为表达式进行评估。如果评估结果非零,则调用Tcl解释器执行body,然后调用解释器执行next,然后重复以上步骤,直到test表达式评估结果为零。如果在body中调用了continue命令,则跳过当前body中continue后面的命令,进入下一次循环。如果在body中调动了break命令,则终止for循环命令。for循环命令返回一个空字符串。

for {set x 0} {$x<5} {incr x} {
puts $x;
}
for循环中的test表达式必须要用大括号包围起来,否则会在for循环之前首先进行变量替换,这会导致test表达式无法感知到变量的变更,从而导致循环不执行或者无限循环。当test表达式被大括号包围起来,会使变量替换延迟到表达式求值时,从而能偶感知变量的变更。具体是无限循环还是循环不执行,取决于变量替换后表达式的值。如果值为非零则会无限循环,否则循环不执行。

 

foreach
foreach varName list body
foreach varlist1 list1 ?varlist2 list2 ...? body
foreach循环命令可以循环一个或多个列表中的值。在循环时,list中的元素会像使用lindex命令一样从前到后依次分配给varName,然后调用Tcl解释器执行body中的命令。

set values {a b c d e f g h}
foreach value $values {
puts $value
}
foreach还可以同时循环多个列表。每个列表都有一个与之对应的循环变量。在每次迭代时都会将list中的值分配给对应的varlist。list中的每个值会按顺序使用一次。最大迭代次数为list的最大元素数,从而保证list中的值一地你给会被迭代一次。如果列表中的值已经分配完毕,但是循环未结束,则使用空字符串填充对应的循环变量。

set values {a b c d e f g h}
set numbers {1 2 3 4 5}
foreach number $numbers value $values {
puts "number:$number->value:$value"
}
list中的值每次可以迭代多个,只需要将varName指定为一个变量列表。每次迭代时会从list中取出列表中变量数量个值,依次分配给变量列表中的变量。当list中元素数量不足时会用空字符串填充变量。

set numbers {1 2 3 4 5}
set values {a b c d e f g h}
foreach {i j k} $values {
puts "$i--$j--$k"
}
foreach number $numbers {i j} $values {
puts "$number--$i--$j"
}


while
while test body
while命令首先计算test表达式的值,如果为true,则调用Tcl解释器执行body中的命令。执行完body中命令后,会再次计算test表达式,重复以上步骤直到test表达式为false为止。如果在body中调用了continue命令,则跳过当前body中continue后面的命令,进入下一次循环。如果在body中调动了break命令,则终止while循环命令。while循环命令返回一个空字符串。

set x 0
while {$x<5} {
puts $x;
incr x;
}
与for命令一样,test表达式必须用大括号包围起来。否则while循环会不执行或者无限循环。

 

break
通常用于循环结构for、foreach、while中提前终止break所在循环。

set x 0
while {$x<5} {
if {$x<3} {
puts $x;
} else {
break;
}
incr x;
}


continue
通常用于循环结构for、foreach、while中提前结束本轮循环。

set x 0
while {$x<5} {
if {$x==3} {
incr x;
continue;
}
puts $x;
incr x;
}

 

 

4、lindex:

语法:lindex list index 
返回list的第index个(0-based)元素。例:

% lindex {1 2 {3 4}} 2 
3 4

 

名称

lindex - 从列表中获得一个元素

语法

lindexlist ?index...?

描述

lindex命令接受一个参数列表list,可以接受0个或者多个index参数,在多个参数的情况下,参数可以是单独的一次排列,也可以是在一个列表当中。

如果不指定index参数:

lindex list

或者

lindex list {}

这种情况下返回lindex列表本身。

当只有一个单独的元素时,lindex命令返回list列表中的第index个元素。替代时元素从0开始(也就是说索引0就是指列表的第一个元素),如果index是负数或者大于列表长度就返回一个空字符串。解释器在解释每一个index值时和string index命令相同,都支持单个和多个index参数。

如果指定了多个index,将会选择列表的子列表中的元素。例如

lindex $a 1 2 3

或者

lindex $a {1 2 3}

与下面的命令相同

lindex [lindex [lindex $a 1] 2] 3

示例lindex {a b c} → a b c
lindex {a b c} {} → a b c
lindex {a b c} 0 → a
lindex {a b c} 2 → c
lindex {a b c} end → c
lindex {a b c} end-1 → b
lindex {{a b c} {d e f} {g h i}} 2 1 → h
lindex {{a b c} {d e f} {g h i}} {2 1} → h
lindex {{{a b} {c d}} {{e f} {g h}}} 1 1 0 → g
lindex {{{a b} {c d}} {{e f} {g h}}} {1 1 0} → g
 

lindex
lindex list ?index1 index2 ...indexN?
从列表中检索元素。 接受0到多个索引。这些索引可以在命令行中连续的给出,也可以将索引放入列表中作为一个参数给出。如果没有提供索引或者提供的是空索引列表,则返回list所有元素值。如果只提供一个单独的索引,则返回列表中该索引处的元素,如果index为负数或者大于等于列表中索引数量,则返回空字符串。单个index的解析与string index命令相同,支持简单的索引计算以及相对于列表末尾的索引计算。如果提供了多个索引,并不是返回多个索引值,而是按顺序从前一次的索引结果中再次索引。

set idx 1
set list1 {a b c {d e {f g h} i } {j k} }
lindex $list1
lindex $list1 {}
lindex $list1 0
lindex $list1 2
lindex $list1 3 2 2
lindex $list1 {3 2 2}
lindex [lindex [lindex $list1 3] 2 ] 2
lindex $list1 end
lindex $list1 end-2
lindex $list1 $idx+1
lindex $list1 $idx-5


5、linsert
linsert list index ?value1 value2...valueN?
将新元素插入列表。在列表的指定位置处插入所有的value,并返回新的列表。linsert不会改变原本的列表,而是生成新的列表。每个value都会做为列表的一个新的元素。如果index小于等于0,则所有新元素将会插入到列表的头部。index大于等于列表长度,则所有元素会插入到列表的尾部。与lindex一样支持string index。

set list1 {a b c {d e {f g h} i } {j k} }
puts $list1
set list2 [linsert $list1 end-1 m n {x y}]
puts $list2
puts $list1


6、lreplace
lreplace list first last ?value1 value2 ... valueN?
使用新元素替换指定索引范围内的旧值,并返回新的列表。first和last分别是被替换的元素的第一个和最后一个元素的索引。与lindex一样支持string index。如果只提供了索引,但是没有提供新的元素,则会删除索引范围内的元素。first与last的不同值会导致不同的行为,如下表:

first last 行为
小于0 小于0 将新元素插入列表头部
小于0 大于等于0 替换从0到last索引处的元素
大于0 小于first 将新元素插入到first索引处
大于0 大于等于first 替换从first到last索引处的元素
大于等于列表元素数量 Tcl8.6起,将新元素追加到列表尾部(之前版本会报错)。
set list1 {a b c d e}


lreplace $list1 -1 -2 1 2 3
lreplace $list1 -1 2 1 2 3
lreplace $list1 3 1 1 2 3
lreplace $list1 1 2 1 2 3
lreplace $list1 5 2 1 2 3
lreplace $list1 1 3


7、lset
lset varName ?index1 index2 ... indexN? newValue
更改列表中的元素。更改列表中指定索引处的元素。接受0到多个索引,这些索引可以在命令行中连续的给出,也可以将索引放入列表中作为一个参数给出。如果没有提供索引或者提供的是空索引列表,则会用新元素替换列表中所有的值。与lindex一样支持string index。

如果newValue中包含空格,则会将紧跟在varName后面的值当作索引解析,从而产生错误或者期望之外的结果。如果newValue为多个想要设置的值可以将newValue用花括号或双引号包围起来。如果newValue为一个值,则需要用“{""}”将newValue包围起来。如果newValue为列表则需要用“"{}"”将newValue包围起来。如果index为负或大于等于列表中的元素数量,则会发生错误。如果提供了多个索引,并不是设置多个索引的值,而是按顺序从前一次的索引结果中再次索引直至最后再进行索引值的替换,索引规则与lindex一致。

set list1 {a b}
set list2 {a b}
puts $list1
lset list1 "a b c d e"
puts $list1
lset list1 {"a b c d e"}
llength $list1
lset list1 "{a b c d e}"
llength $list1
lset list1 "a b c d e"
puts $list1
lset list2 "$list1"
llength $list2
lset list2 "{$list1}"
llength $list2
set mList { {a b c} {d e f} {g h i}}
lset mList 1 2 k
puts $mList

 

 

8、llength - 计算列表的元素个数

语法

llength list

描述

list当作一个列表来处理并返回一个十进制数的字符串表示列表中元素的个数。

示例

结果是列表元素的个数:

% llength {a b c d e}
5
% llength {a b c}
3
% llength {}
0

元素并不一定是严格按照字典来的词,特别是当使用“{}”符号时:

% llength {a b {c d} e}
4
% llength {a b { } c d e}
6

一个空列表不一定是一个空字符串:

% set var { }; puts "[string length $var],[llength $var]"
1,0

 

 

9、incr - 增加变量的值

语法

incr varName ?increment?

描述

增加储存在变量varName中的值,变量的值必须是一个整数,如果increment变量提供了,那么增加的值为increment的值,否则就增加1。新的值储存在变量varName中并且返回。


从Tcl8.5开始,传递给incr的变量varName可能被unset,在这种情况下varName可能被赋值为increment或者默认的1。

示例

变量x的值增加1:

incr x

变量x的值增加42:

incr x 42

变量x的值增加变量y:

incr x $y

变量x的值不增加(经常用来检查一个过程的变元是否是整数,如果不是整数就返回一个错误):

incr x 0

 

 

10、global - 存取全局变量

语法

global varname ?varname ...?

描述

这个命令命令只有在一个过程的上下文中才有效果,如果global命令在过程的上下文中运行,它就创建一个局部变量,这个变量链接相应的全局变量。

如果varname包含了一个名字空间限定词,这个局部变量的名字是非法的全局变量,应该由namspace tail命令指定为一个名字空间变量。

varname被当作是变量名,不能是数组元素,如果是数组元素格式的变量名就返回一个错误。

示例

这个过程设置名字空间变量::a::x

proc reset {} {
    global a::x
    set x 0
}

这个过程将字符串加到一个全部缓存中,字符串由换行符隔开。这种方法对想要逐步创建一条消息是很有用的,可以在过程当中添加消息内容。(比如在通过socket的一个打开的连接或者作为HTTP响应)。

proc accum {string} {
    global accumulator
    append accumulator $string /n
}
 
 

11、lsort - 给列表中的元素排序

语法

lsort ?optionslist

描述

这个命令对list中的元素进行排序,返回一个重新排序的列表。lsort命令的执行使用归并排序算法,所以排序性能稳定在(n log n)的级别。

默认使用ASCII表排序,但是以下的options选项也可以控制排序的方式:

-ascii
使用 ASCII表的字符顺序排序,默认方式。
-dictionary
使用字典关系,基本上和 -ascii差不多,区别在于 -dictionary忽略了大小写关系,而且把数字字符看作是数值来处理。比如在 -dictionary模式,bigBoy在bigbang和bigboy中间,x10y在x9y和x11y之间。
-integer
把列表元素转换成整数并且使用整数关系排序。
-real
把列表元素转换成浮点数并且使用浮点数关系排序。
-command command
使用 command作为一个比较命令,比较两个元素。这个命令需要返回一个整数,表示小于、等于或大于0,分别对应第一个元素是小于、等于还是大于第二个元素。
-increasing
排序时按照由小到大的顺序排列,默认方式。
-decreasing
排序时按照由大到小的顺序排列。
-indices
返回一个列表,包含的元素是排序后的元素对应以前的 list的索引。
-index indexList
如果指定了这个选项,那么 list的元素必须是一个合法的Tcl子列表,将会根据子列表来进行排序,举例如下:
lsort -integer -index 1 /
      {{First 24} {Second 18} {Third 30}}
返回 {Second 18} {First 24} {Third 30}, and
lsort -index end-1 /
      {{a 1 e i} {b 2 3 f g} {c 4 5 6 d h}}
返回 {c 4 5 6 d h} {a 1 e i} {b 2 3 f g}, and
lsort -index {0 1} {
   {{b i g} 12345}
   {{d e m o} 34512}
   {{c o d e} 54321}
}
返回 {{d e m o} 34512} {{b i g} 12345} {{c o d e} 54321} (因为e排列在i前,i排列在o前。)这个选项在这种方式的比较中比 -command更有效。
-nocase
进行排序的时候不考虑大小写,如果与 -dictionary、 -integer、或 -real命令合并使用则没有作用。
-unique
如果这个选项指定了,如果遇到相同的比较元素,那么只保留最后的那个,其它的全部删除掉。因此如果 -index 0使用了,那么{1 a}和{1 b}比较时就是相同的,所以只有{1 b}返回。

注意

lsort命令只用来控制使用什么样的排序关系,并不改变数值本身,lsort命令是安全的当用于-command选项时。

示例

使用ASCII对列表排序:

% lsort {a10 B2 b1 a1 a2}
B2 a1 a10 a2 b1

使用字典关系对列表排序:

% lsort -dictionary {a10 B2 b1 a1 a2}
a1 a2 a10 b1 B2

使用整数关系对列表排序:

% lsort -integer {5 3 1 2 11 4}
1 2 3 4 5 11
% lsort -integer {1 2 0x5 7 0 4 -1}
-1 0 1 2 4 0x5 7

使用浮点数关系对列表排序:

% lsort -real {5 3 1 2 11 4}
1 2 3 4 5 11
% lsort -real {.5 0.07e1 0.4 6e-1}
0.4 .5 6e-1 0.07e1

使用索引对列表排序:

% # Note the space character before the c
% lsort {{a 5} { c 3} {b 4} {e 1} {d 2}}
{ c 3} {a 5} {b 4} {d 2} {e 1}
% lsort -index 0 {{a 5} { c 3} {b 4} {e 1} {d 2}}
{a 5} {b 4} { c 3} {d 2} {e 1}
% lsort -index 1 {{a 5} { c 3} {b 4} {e 1} {d 2}}
{e 1} {d 2} { c 3} {b 4} {a 5}

剥离重复的数据:

% lsort -unique {a b c a b c a b c}
a b c

返回排序后元素在原序列的索引:

% lsort -indices {c a b}
1 2 0

更加复杂的排序方式:

% proc compare {a b} {
    set a0 [lindex $a 0]
    set b0 [lindex $b 0]
    if {$a0 < $b0} {
        return -1
    } elseif {$a0 > $b0} {
        return 1
    }
    return [string compare [lindex $a 1] [lindex $b 1]]
}
% lsort -command compare /
        {{3 apple} {0x2 carrot} {1 dingo} {2 banana}}
{1 dingo} {2 banana} {0x2 carrot} {3 apple}
 
12、if
TCL 对于格式的要求很严格,什么空格都不能乱有。。真是服了。。
对于if while switch 等等都是这样子吧~ 其中“_”代表空格
1. 条件判断的花括号和具体操作前面的花括号之间一定要有个 空格
2. 具体操作 单独一行
3. 具体操作之后的花括号另起一行,要和elseif 或 else  同一行 ,中间隔个 空格
 
if_{$x_>_0}_{
......
}_elseif_{$x_==_1}_{
.......
}_else_{
.......
}
posted @ 2022-01-24 15:36  我家有只江小白  阅读(380)  评论(0编辑  收藏  举报