TCL命令集合
eval命令本身使用非常简单,但是用处非常大,如果需要动态的构造命令,那么必须使用eval命令。
eval命令参考:http://blog.csdn.net/dulixin/archive/2008/03/27/2223978.aspx
catch命令可以用来捕获一个错误,一个没有捕获的错误将终止脚本的执行。error会产生一个错误,error命令产生的错误如果没有被catch捕获将会导致脚本的终止。
foreach循环,格式为:
after有几种形式,使用比较灵活。
variable - 创建和初始化一个名字空间变量
语法
variable ? name value...? name ? value?描述
这个命令一般在名字空间中创建一个或多个变量,每个变量 name使用 value初始化,最后一个变量的 value是可选的。如果变量name不存在,就创建一个,在这种情况下,如果指定了value,就把它的值赋值给创建的变量,如果不指定value,新的变量name就没有初始化。如果变量已经存在,就赋值value,没有指定value则保持原来的值。一般来说name不做任何限定(不包含名字空间限定),并且在当前名字空间中创建,如果name包含有名字空间限定,变量就创建在指定的名字空间中,如果变量没有定义,对于namespace which命令来说就是可见的,但是对info exists命令来说是不可见的。
如果variable命令在一个tcl过程中执行,就创建一个局部变量,这个局部变量链接一个相关的名字空间变量(因此这些变量由info vars列出),这样variable命令类似global命令,虽然global命令只是链接一个在全局范围内的变量,如果给出了values,就用来修改相关名字空间变量,如果一个名字空间变量不存在,就创建一个并且初始化。
name变元不能引用一个数组的元素,但是name可以引用整个数组并且初始化的value必须符合数组的要求,声明过变量后,数组中的元素可以使用set和array命令来配置。
示例
在名字空间中创建一个变量:namespace eval foo { variable bar 12345 }
在名字空间中创建一个数组:
namespace eval someNS { variable someAry array set someAry { someName someValue otherName otherValue } }
为一个过程存取名字空间中的变量:
namespace eval foo {
proc spong {} {
# Variable in this namespace
variable bar
puts "bar is $bar"
# Variable in another namespace
variable ::someNS::someAry
parray someAry
}
}
uplevel - 在不同的堆栈层中执行一个脚本
语法
uplevel ?level? arg ?arg ...?
描述
所有的arg变元使用concat命令风格连接起来,连接起来的命令在level指定后的作用域中执行,uplevel返回执行结果。(堆栈层可以看作是变量起作用的范围)
如果level是一个整数,它指出了调用命令的堆栈距离目前调用堆栈的层数,如果level是以#后面加一个数字,那么这个数字就是命令执行的绝对堆栈层,缺省值为1,如果有了#符号那么后面必须跟一个数字。
例如,假设过程a在最高层调用,然后a调用b,再后来b调用c,假设c调用uplevel名令,如果level是1或者#2或者忽略掉,这个命令将在b的变量的作用域中执行,如果level是2或者#1,那么这个命令将在a的变量的作用域中执行,如果level是3或者#0,这个命令将在最高层执行(只有全局变量是可见的)。
uplevel命令导致在调用过程的堆栈层中"看不到"过程了,在下面的例子里,假设c调用命令:
uplevel 1 {set x 43; d}当d是另外一个过程时,set命令会在b的作用域中修改变量x,d将在第三层堆栈运行,就像是b过程调用的d过程。
uplevel {set x 42}set命令将会修改在b作用域中的x变量,在执行d的时候过程c对于调用堆栈层是不可见的,命令info level可以获得当前程序的堆栈层。
uplevel可以实现新的控制结构,例如,uplevel可以实现while过程。
示例
uplevel命令在实现新的控制结构方面非常有用,下面的例子显示了它可以用来创建一个do命令:
proc do {body while condition} {
if {$while ne "while"} {
error "required word missing"
}
set conditionCmd [list expr $condition]
while {1} {
uplevel 1 $body
if {![uplevel 1 $conditionCmd]} {
break
}
}
}
array - 处理数组变量
语法
array option arrayName ?arg arg ...?
描述
这个命令执行几种可选项中的一个操作,操作的对象为arrayName,除非以下的命令特殊声明,否则arrayName必须是存在的数组变量名称。option变元决定了要对数组变量进行什么样的操作,具体如下:
-
array anymore arrayName searchId
- 如果在一次数组搜索当中数组中还有剩余的元素就返回 1,如果没有剩余的元素就返回 0。 searchId指定了被检查 arrayName的搜索标示符,这个标示符必须是命令 array startsearch返回的搜索标示符。这个命令在数组有空索引的元素时非常有用,因为 array nextelement的返回值并不能说明搜索是否完毕。 array donesearch arrayName searchId
- 这个命令终结一次数组搜索, searchId指出了需要终结的数组搜索标示符,这个标示必须是命令 array startsearch返回的搜索标示符。返回一个空字符串。 array exists arrayName
- 如果 arrayName是一个数组变量就返回 1,如果没有这个变量或者是非数组变量就返回 0。 array get arrayName ?pattern?
- 返回一个列表,列表中的元素是成对的,交替的出现索引和对应数组值,如果不指定 pattern,所有数组的元素都回返回,如果指定了 pattern,只有匹配 pattern(与 string match匹配风格相同)的数组元素返回。如果 arrayName不是一个数组变量的名字或者没有包含任何元素就返回一个空列表。 array names arrayName ?mode? ?pattern?
- 返回一个匹配 pattern的数组元素索引的列表,mode可以是 -exact、 -glob或 -regexp中的一个,指定了匹配的风格,如果不指定 mode,默认为 -glob。如果需要了解详细的匹配风格请参考 string match和 regexp。如果不指定 pattern则返回数组中所有的索引,如果 arrayName不是一个数组变量的名字或者没有包含任何元素就返回一个空列表。 array nextelement arrayName searchId
- 返回 arrayName数组中的下一个元素索引,如果数组中所有的元素都搜索到了就返回空字符串, searchId指出了需要终结的数组搜索标示,这个标示必须是命令 array startsearch返回的搜索标示。警告:如果数组中有添加和删除元素的操作,那么所有的搜索都回自动结束,就像是调用了 array donesearch,这将会导致 array nextelement操作失败。 array set arrayName list
- 设置一个或多个数组元素, list必须是像 array get返回值风格的列表,第奇数个列表元素被认为是 arrayName的一个元素索引,紧接着的第偶数个列表元素就被当作前一个元素的数组中的值,如果变量 arrayName不存在或者为空,就创建一个空数组 arrayName。 array size arrayName
- 返回一个十进制的字符串数值来指出数组中元素的数量,如果 arrayName不是一个数组的名字就返回 0。 array startsearch arrayName
- 这个命令开始在 arrayName数组中进行一个元素一个元素的搜索, array nextelement命令返回下一元素的索引,当搜索完毕, array donesearch命令必须调用,返回值是一个搜索标示符,这个搜索表示符可以在 array nextelement和 array donesearch中使用来标示操作的搜索,通过使用搜索标示符允许对一个数组同时进行不同的搜索。目前,普遍使用的方式是使用 array get和 array names与 foreach一起使用来遍历数组中的每一个元素。具体请参考下面的示例。 array statistics arrayName
- 返回数组中元素在哈希表的分配方式的统计,这个命令包含表格中条目数,buckets数目和buckets的利用情况。 array unset arrayName ?pattern?
- 删除数组中所有匹配 pattern的元素(与 string match匹配风格相同),如果 arrayName不是一个数组变量或者没有匹配到任何元素,不会产生错误,如果忽略了 pattern变元并且 arrayName是一个数组名称,这个命令将删除整个数组所有的元素,这个命令总是返回一个空字符串。
示例
array set colorcount {
red 1
green 5
blue 4
white 9
} foreach {color count} [array get colorcount] {
puts "Color: $color Count: $count"
}
→ Color: blue Count: 4
Color: white Count: 9
Color: green Count: 5
Color: red Count: 1
foreach color [array names colorcount] {
puts "Color: $color Count: $colorcount($color)"
}
→ Color: blue Count: 4
Color: white Count: 9
Color: green Count: 5
Color: red Count: 1 foreach color [lsort [array names colorcount]] {
puts "Color: $color Count: $colorcount($color)"
}
→ Color: blue Count: 4
Color: green Count: 5
Color: red Count: 1
Color: white Count: 9 array statistics colorcount
→ 4 entries in table, 4 buckets
number of buckets with 0 entries: 1
number of buckets with 1 entries: 2
number of buckets with 2 entries: 1
number of buckets with 3 entries: 0
number of buckets with 4 entries: 0
number of buckets with 5 entries: 0
number of buckets with 6 entries: 0
number of buckets with 7 entries: 0
number of buckets with 8 entries: 0
number of buckets with 9 entries: 0
number of buckets with 10 or more entries: 0
average search distance for entry: 1.2
列表操作在脚本中使用的频率非常高,基本上每个脚本都会涉及到其中的一些操作,在这里对列表的命令进行实例解析,以加深对列表命令的理解,本文涉及的命令为list、concat、lrepeat、join和split。
使用重复的元素构建列表,number为重复的次数,element为重复的元素,这个命令就相当于对重复number次的element元素进行了list操作,所以lrepeat 1 arg ... 和list arg ... 执行结果相同。如下例:
% lrepeat 3 This is a tcltk example
This is a tcltk example This is a tcltk example This is a tcltk example
下例与list命令结果相同:
% lrepeat 1 This is a tcltk example
This is a tcltk example
两个嵌入式标志位:
列表操作在脚本中使用的频率非常高,基本上每个脚本都会涉及到其中的一些操作,在这里对列表的命令进行实例解析,以加深对列表命令的理解,本文涉及的命令为lappend、lreplace、lset、linsert、lsort和lreverse。
concat ?arg arg …?
此命令把每个参数连接在一起,并去掉第一个参数和最后一个参数前的前导和尾部空白。如果所有的参数都是列表,则把所有的列表并置为单一的列表。此命令可以有任意数量的参数arg;如果没有提供参数arg,则此命令的结果是一个空字符串。
例子:
concat会连接列表,所以下面的命令:
concat a b {c d e} {f {g h}}
会返回“a b c d e f {g h}”。此命令也可连接非列表的数据类型,因此下面的命令:
concat “
会返回“a b {c d e} f”。
注意,并置不会删除参数间的空白,所以命令:
concat “a
会返回“a
join list ?joinString?
把列表的元素连接起来而创建一个字符串。参数list必须是效的Tcl列表。此命令返回格式化后的字符串(把列表list的所有元素用字符串joinString连接相邻的元素而构成)。参数joinString默认为是一个空格字符。
例子:
用逗号分隔列表的元素:
set data {1 2 3 4 5}
join $data ", "
使用join去展平列表为单层的列表:
set data {1 {2 3} 4 {5 {6 7} 8}}
join $data
lappend varName ?value value value …?
把值添加到列表中。此命令把变量varName视为列表,并且把每个参数value作为单独的元素添加到列表varName的值中,每个元素用空格分隔。如果varName不存在,则被创建为列表,而其值就是参数value。lappend与append相似,除了value是作为列表被添加而不是作为原始的文本。此命令提供了一个相对有效的方法构建一个大型的列表。例如,当$a很长时,“lappend a $b”比“set a [concat $a[list $b]]”更有效。
例子:
使用lappend去构建一个数字列表:
set var 1
à 1
lappend var 2
à 1 2
lappend var 3 4 5
à 1 2 3 4 5
lassign list ?varName …?
此命令把列表list的元素相续按顺序地赋给参数varName。如果变量varName的个数比列表元素的个数多,则剩余的变量varName被设置为空字符串。如果列表元素的个数比变量varName的个数多,则此命令返回没有被赋给变量的元素。
例子:
下面的例子说明了是怎样多重赋值的,和当如果太少或太多元素会发生什么:
lassign {a b c} x y z
puts $x
puts $y
puts $z
lassign {d e} x y z
puts $x
puts $y
puts $z
lassign {f g h i} x y
puts $x
puts $y
lassign命令也有其它的用法。它可以用于创建类似于其它shell语的“shift”命令:
set ::argv [lassign $::argv argumentToReadOff]
lindex list ?index …?
检索列表中的元素。索引可以在命令行连续地提交,或组合为一个列表作为单个参数提交。如果没有提供索引,则命令采取的形式为:
lindex list
在此情况中,lindex的返回值就是参数list的值。
当只提供单个索引时,lindex命令返回列表中第index个元素(列表元素的索引从0开始计算)。在提取元素时,lindex遵守大括号,双引号和反斜杠的规则;但,不会发生变量替换和命令替换。如果index是一个负数或者是大于或等于元素的数量,则返回一个字符串。对每个简单的index值的解释,与命令string index相同,支持简单的索引算术运算和相对于列表尾端的索引(用end表示列表的尾端)。
如果提供额外的参数index,则每个参数依次选取一个元素,允许脚本从子列表中选取元素。命令:
lidnex $a 1 2 3
等同于:
lindex [lindex [lindex $a 1] 2 ] 3
例子:
列表可以从两端索引:
lindex {a b c} 0
lindex {a b c} 2
lindex {a b c} end
lindex {a b c} end-1
列表或索引的序列可以从列表中的列表选取元素:
lindex {a b c}
lindex {a b c} {}
lindex {{a b c} {d e f} {g h i}} 2 1
lindex {{a b c} {d e f} {g h i}} {2 1}
lindex {{{a b} {c d}} {{e f} {g h}}} 1 1 0
lindex {{{a b} {c d}} {{e f} {g h}}} {1 1 0}
列表索引也可以执行有限的计算,从其它索引中相加或减去固定的数量:
set idx 1
lindex {a b c d e f} $idx+2
à d
set idx 3
lindex {a b c d e f} $idx+2
à f
linsert list index ?element element …?
在列表中插入元素。此命令通过在列表list的第index个元素前插入所有的参数element而创建一个新的列表。每个参数element都会成为新列表中的一个单独元素。如果index小于或等于0,则新的元素插入列表的前头。对index值的解释,与命令string index相同,支持简单的索引算术运算和相对于列表尾端的索引(用end表示列表的尾端)。
例子:
set $a {0 1 2 3 4 5}
linsert $a 2 “hello”
把一些值放入一个列表中,首先从开头索引,然后从尾端索引,然后将他们链接一起:
set oldList {the fox jumps over the dog}
set midList [linsert $oldList 1 quick]
set newList [linsert $midList end-1 lazy]
# The old lists still exist though...
set newerList [linsert [linsert $oldList end-1 quick] 1 lazy]
list ?arg arg …?
创建一个列表。此命令返回由所有arg构成的列表,或者如果没有提供arg则返回一个空字符串。在需要时添加大括号和反斜杠,以便lindex命令可在此命令的结果上使用重新抽取原始的参数;并且也可以用eval执行生成的列表,arg1构成命令的名称,而其他args构成此arg1命令的参数。list生成的结果与concat稍微不同:concat会在形成列表前删除一层的组合,而list直接由原始的参数生成列表。
例子:
命令
list a b "c d e
会返回
a b {c d e
而相同参数的concat会返回
a b c d e f {g h}
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
lrange list first last
返回列表中一个或多个相邻的元素。list必须是有效的Tcl列表。此命令返回一个新列表,新的列表由从列表list中的first到last的元素组成(包括first和last的元素)。对索引值first和last的解释与命令string index的索引值相同,支持简单的索引算术运算和相对于列表尾端的索引(用end表示列表的尾端)。如果first小于0,则它被视为0。如果last大于或等于list的元素数量,则它被视为是end。如果first比last大,则返回一个空字符串。注意,“lrange list first first”并不总是产生与“lindex list first”相同的结果(虽然对于没有用大括号括住的简单字段,此两个命令所产生的结果相同);但“lrange list first first”与“list [lindex list first]” 产生的结果相同。
例子:
选择头两个元素:
% 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}
lrepeat count ?element …?
此命令创建一个列表,此列表的元素就是重复count次的元素的序列element…。count必须是一个非负整数,element可以任何的Tcl值。注意,“lrepeat 1 element…”等同于
“list element…”
例子:
lrepeat 3 a
lrepeat 3 [lrepeat 3 0]
lrepeat 3 a b c
lrepeat 3 [lrepeat 2 a] b c
lreplace list first last ?element element…?
lreplace返回一个新列表,通过用参数element代替一个或多个list的元素而形成的新列表。索引值first和last指定了代替范围的第一个和最后一个元素。对索引值first和last的解释与命令string index的索引值相同,支持简单的索引算术运算和相对于列表尾端的索引(用end表示列表的尾端)。0表示列表的第一个元素,而end表示列表的最后一个元素。如果list为空,则忽略first和last。
如果first小于0,则它被视为指向列表第一个元素的前面。对于非空列表,first指示的元素必须存在,或者first必须指向列表的开头。
如果last小于first,则任何指定的元素都会被插入到由first指定的位置中,而没有元素被删除。
参数element指定了零个或多个新的参数,添加到列表中那些已被删除的元素的位置处。每个参数element将成为一个单独的列表元素。如果没有指定参数element,则first和last间的元素只是简单地被删除。如果list为空,则任何的参数element被添加到列表的末尾。
例子:
用一个参数element代替列表中的一个元素:
% lreplace {a b c d e} 1 1 foo
à a foo c d e
用三个参数element代替列表中的两个元素:
% lreplace {a b c d e} 1 2 three more elements
à a three more elements d e
删除列表中的最后一个元素:
% set var {a b c d e}
à a b c d e
% set var [lreplace $var end end]
à a b c d
从列表中删除一个给定的元素的过程:
proc lremove {listVariable value} {
}
lreverse list
此命令返回一个列表,其元素与列表list相同,但元素的顺序相反。
例子:
lreverse {a a b c}
lreverse {a b {c d} e f}
lsearch ?options? list pattern
查看列表是否包含一个特定的元素。这个命令搜索列表的元素,查看他们是否与pattern匹配。如果匹配,则命令返回第一个匹配的元素的索引(除非指定了选项-all或-inline)。如果没有匹配的,则命令返回-1。参数option指示列表的元素是怎么样与pattern相匹配的,并且option的值必须是下面其中之一:
MATCHING STYLE. OPTIONS匹配风格的选项
如果省略所有的匹配风格选项,则默认的匹配风格是-glob。如果指定了多种匹配风格,则最后的匹配风格起作用。
-exact
pattern是一个字面值字符串,与每个表元素进行精确的比较。
-glob
pattern是一个glob风格的模式,例用string match命令相同的规则与每个表元素比较。
-regexp
pattern被视为一个正则表达式,使用在re_syntax所描述的规则与每个表元素比较。
-sorted
列表的元素按顺序排序。如果指定这个选项,则lsearch将使用一个更加有效的搜索算法来搜索列表。如果没有指定其它选项,则列表list被假定为按升序排序,并且包含ASCII字符串。这个选项与-glob和-regexp互斥,当指定-all或-not时,被视为与-exact完全一样。
GENERAL MODIFIER OPTIONS一般的修饰词选项
这些选项可以与所有的匹配式样联用。
-all
把结果改变为是列表中所有匹配的索引(或者如果也指定了-inline,则是列表中所有匹配的值)。如果返回的是索引,则索引是以数值排序的。如果返回的是值,则值的顺序将是输入列表list中的那些值的顺序。
-inline
返回的是匹配的值而不是匹配的索引(或者是一个空字符串,如果没有值匹配的话)。如果也指定了-all,则此命令的结果是列表中所有匹配的值。
-not
这是对匹配的否定,返回的是列中第一个非匹配的值的索引。
-start index
在位置index处开始搜索列表。对index值的解释与命令string index相同,支持简单的索引算术运算和相对于列表尾端的索引。
CONTENTS DESCRIPTION OPTIONS内容描述的选项
这些选项描述列表中被搜的项目是怎样被解释的。当它们与-exact和-sorted选项联用时,它们才是有意义的。如果指定了多个选项,则最后一个选项起作用。默认是-ascii。
-ascii
列表的元素是作为Unicode字符串被检验(这为向后兼容性的原因)。
-dictionary
列表的元素使用字典风格式的比较而进行比较(对于更完整的描述参考lsort)。注意,当给出-sorted选项时,此选项与-ascii选项才有有意义的差别,因为当精确相等时值才是字典式的相等。
-integer
列表元素作为整数比较。
-nocase
比较以忽略大小写的方式处理。如果与-dictionary,-integer或-real选项联用时,则没有效果。
-real
列表元素作为浮点值比较。
SORTED LIST OPTIONS用于排序的列表选项
这些选项(与-sorted选项联用时才有意义)指定列表是怎样被排序的。如果给出多个选项,则最后一个起作用。默的选项是-increasing。
-decreasing
列表的元素以降序排序。当与-sorted联用时,此选项才有意义。
-increasing
列表元素以升序排序。当与-sorted联用时,此选项才有意义。
-bisect
当列表元素按顺序排序时,进行不精确的搜索。对于升序的列表,小于或等于模式的最后一个索引的元素被返回。对于降序的列表,大于或等于模式的最后一个索引的元素被返回。如果模式是在第一个元素之前或列表是空列表,则返回-1。此选项暗示(隐式地使用)-sorted,不能与-all或-not联用。
NESTED LIST OPTIONS嵌套的列表选项
这些选项被用于搜索列表的列表。它们可以与任何其它的选项联用。
-index indexList
此选项是用于搜索嵌套的列表。参数indexList给出了在每个元素中的索引的路径(可能与lindex或lset命令联用),以允许被匹配的术语的位置。
-subindices
如果给出了此选项,此命令的索引结果(或者当也指定了-all时,每个索引结果)将是在整个列表内找到的项目的完整的路径(适用于与lindex或lset联用)。除非也指定了-index,否则此选项没有效果,它只是一个方便的快捷方式。
例子:
基本的搜索:
lsearch {a b c d e} c
lsearch -all {a b c a b c} c
使用lsearch过滤列表:
lsearch -inline {a20 b35 c47} b*
lsearch -inline -not {a20 b35 c47} b*
lsearch -all -inline -not {a20 b35 c47} b*
lsearch -all -not {a20 b35 c47} b*
甚至可以执行“set-like”的删除操作:
lsearch -all -inline -not -exact {a b c a d e a f g a} a
Searching may start part-way through the list:
可以用部分的方式开始搜索整个列表:
lsearch -start 3 {a b c a b c} c
也可以搜索内部的元素:
lsearch -index 1 -all -inline {{a abc} {b bcd} {c cde}} *bc*
lset varName ?index ...? newValue
更改列表中的元素。varName它是一个Tcl列表。索引可以在命令行连续的提供或组合为一个列表作为单个参数提供。newValue是列表narName中某一元素的新值。如果没有提供索引,则命令的形式为:
lset varName newValue
或
lset varName {} newValue
在这种情况中,newValue代替变量varName的旧值。
当只提供一个索引时,它寻址列表varName中第index个元素。当作列表解释的varName,lset遵守有关作为Tcl命令解释器的花括号、双引号和反斜线的相同规则;然而,不发生变量替换和命令替换。此命令构造一个新的列表,指明的元素被newValue代替。这个新列表存储在变量varName中,并且作为lset命令的返回值。
如果index是负数,或大于$varName的元素数量,则发生一个错误。如果index等于$varName的元素数量,则给定的元素(newValue)被添加到列表末尾。
对于index值的解释与命令string index相同,支持简单的索引算术运算和相对于列表的尾端的索引。
如果提供多个参数index,则每个参数依次被用于在由前一个索引操作指定的sublist中寻址一个元素(即是索引列表中的子列表的元素),允许脚本改变在sublists中的元素(或将元素添加到sublists中)。命令,
lset a 1 2 newValue
或
lset a {1 2} newValue
用newValue代替sublist 1的索引为2的元素 。
每个参数index必须是大于或等于零的整数。每个参数index必须小于或等于相应列表的长度。换句话说,lset命令只能通过添加一个元素而改变一个列表的大小(将新的元素添加到原列表的后面)。如果索引超出了允许的范围,则引发一个错误。
例子:
下面每个例的x,它的初始值为:
set x [list [list a b c] [list d e f] [list g h i]]
下列每个命令的返回值也成为了x的新值(除了最后一个命令外,它发生错误,而x的值不变)。
lset x {j k l}
lset x {} {j k l}
lset x 0 j
lset x 2 j
lset x end j
lset x end-1 j
lset x 2 1 j
lset x {2 1} j
lset x {2 3} j
在下列例子中,x的初始值为:
set x [list [list [list a b] [list c d]] \
指示返回值也将成为 x 的新值。
lset x 1 1 0 j
lset x {1 1 0} j
lsort ?options? list
排序列表的元素。此命令排序列表list的元素,返回一个按顺序排序的新列表。lsort命令的实现使用一个稳定排序具有O(n log n)性能特征的合并排序算法。
默认使用ASCII排序,结果以升序返回。然而,在列表list的前面,可以指定下列任何的选项,以控制排序的进程(接受唯一的缩写):
-ascii
使用Unicode码位排序规则顺序(名称是为了向后兼容的原因)比较字符串。这是默认选项。
-dictionary
使用字典式的比较。这与-ascii一样,除了(a)忽略大小写(tie-breaker关系断路器除外),(b)如果两个字符串包含有嵌入的数字,数字作为整数比较而不是作为字符。例如,在-dictionary模式中,bigBoy排在bigbang和bigboy之间,而x10y排在x9y和x11y之间。
-integer
把列表元素转换成整数并使用整数比较。
-real
把列表元素转换成浮点数并使用浮点数比较。
-command command
使command作为一个比较命令。要比较两个元素,评估由命令组成的脚本,此命令带有两个元素作为额外的参数。大如果第一个元素小于,等于,或大于第二个元素,则此本应返回一个小于,等于,或大于0的整数。
-increasing
以升序对列表排序(最小的元素在第一)。这是默认。
-decreasing
以降序对列表排序(最大的元素在第一)。
-indices
返回列表中排序的索引,而不是索引对应的值。
-index indexList
如果指定了这个选项,则列表list中的每个元素它自己必须是一个适当的sublist(子列表)(除非使用了-stride)。不是基于整个sublists排序,而是lsort将从每个sublist中提取第 indexList个元素(好像全部的元素和indexList被传递给了lindex)并且基于给定的元素排序,例如:
lsort -integer -index 1 \
返回{Second 18} {First 24} {Third 30},
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},而
lsort -index {0 1} {
}
返回{{d e m o} 34512} {{b i g} 12345} {{c o d e} 54321}(因为e排在i的前面,而i排在o的前面)这个选项比使用-command完成同样的效果更有效。
-stride strideLength
如果指定了这个选项,列表被视为由strideLength个元素组成,这些组合要么由他们的第一个元素排序,或者,如果指定了-index选项,则由传递给-index(则由-index忽略)的第一个索引指示的每一组中的元素来排序。在各个组中的元素总是在同一位置。
列表的长度必须是strideLength乘以一个整数,至少是2。例如,
lsort -stride 2 {carrot 10 apple 50 banana 25}
返回“apple 50 banana 25 carrot 10”,而
lsort -stride 2 -index 1 -integer {carrot 10 apple 50 banana 25}
返回“carrot 10 banana 25 apple 50”。
-nocase
比较以忽略大小写的方式处理。如果与-dictionary,-integer,或-real联用,则没有效果。
-unique
如果指定这个选项,则只有列表中最后一组重复的元素被保留。注意,重复的元素由相对于在排序中使用的比较来确定。因此如果使用了-index 0,则{1 a}和{1 b}将被视为重复,而只有第二个元素,{1 b},被保留。
注意
lsort的选项只是控制使用什么样的比较,而不必强制值它们本身实际上是什么。当要排序的列表少于两个元素时,这区别仅是显而易见的。
lsort命令是reentrant(可重入的),这意味着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
使用索引排序
% # 注意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}
排序字典:
% set d [dict create c d a b h i f g c e]
à c e a b h i f g
% lsort -stride 2 $d
à a b c e f g h i
使用-stride和多个索引排序:
% # 注意,第一个索引值是相对于组的
% lsort -stride 3 -index {0 1} {{Bob Smith} 25 Audi {Jane Doe} 40 Ford}
à {{Jane Doe} 40 Ford {Bob Smith} 25 Audi}
使用排序删除多个重复的值 :
% lsort -unique {a b c a b c a b c}
à a b c
使用比较函数进行更复杂的排序:
% proc compare {a b} {
}
% lsort -command compare \
{1 dingo} {2 banana} {0x2 carrot} {3 apple}
split string ?splitChars?
返回一个用参数splitChars中的每个字符折分string而形式的列表。结果列表中的每个元素由string中每个splitChars字符间的字符组成。如果string中包含两个连续的splitChars字符,则会产生一个空元素,或者string中的第一个字符或最后一个字符是splitChars中的字符,也会产生一个空元素。如果splitChars是空字符串,则string中的每个字符成为结果列表中的每个元素。splitChars默认为空格。
例子:
折分USENET组名为各个分层组件:
split "comp.lang.tcl" .
下面看看是如何用splitChars中的每个字符来折分string的,如果不小心可能会导致遗失某些信息:
split "alpha beta gamma" "temp"
从一个格式化得不好列表字符串中提取列表的words:
split "Example with {unbalanced brace character"
字符串的每个字符成为列表的一个元素:
split "Hello world" {}
分析面向记录的文件
分析Unix的/etc/passwd文件,一行一个记录,而每一行是用冒号分隔的字段列表:
## Read the file
set fid [open /etc/passwd]
set content [read $fid]
close $fid
## Split into records on newlines
set records [split $content "\n"]
## Iterate over the records
foreach rec $records {
}
lindex - 从列表中获得一个元素
语法
lindex list ?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