TCL命令
TCL命令集合
eval命令本身使用非常簡單,但是用處非常大,如果需要動態的構造命令,那麼必須使用eval命令。
eval命令參考:http://blog.csdn.net/dulixin/archive/2008/03/27/2223978.aspx
<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
after有幾種形式,使用比較靈活。
<wbr><wbr><wbr><wbr>
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。
<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
使用重複的元素構建列表,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<wbr><wbr><wbr><wbr>
<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
兩個嵌入式標誌位:
<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
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
相關文章
- TCL - info命令
- TCL學習之info命令
- TCL: LIST命令-lsearch, lsort, lrange
- TCL指令碼讀取命令列引數指令碼命令列
- Tcl/Tk 命令與C/C++的整合研究C++
- TCL 750評測 TCL 750值得買嗎?
- 用TCL(工具命令語言)管理Tornado (for VxWorks) 可啟動工程
- Manipulating Files With Tcl
- tcl列表操作lsearch
- TCL集團改名為TCL科技(蘋果企業開發者賬號)蘋果
- TCL手機TCL 750正式釋出 售價1993元
- 智慧時代的TCL之舞
- Tcl語法簡介
- TCL檔案查詢拆分
- TCL實業、TCL科技加入聯合國全球契約組織,攜手共建更好世界
- TCL: 變數和過程variable變數
- tcl/tk詳解——glob使用例解
- c++/tcl程式設計總結C++程式設計
- 使用Tcl操作Excel檔案的方法Excel
- Oracle DDL,DML,DCL,TCL 基礎概念Oracle
- tcl/tk參考——控制結構catch
- tcl/tk參考——控制結構errorError
- TCL電子財報:2022年TCL 電子營收為713.51億港元 同比下跌4.7%營收
- TCL空調售後服務維修電話/官方統一24小時TCL客服熱線號碼
- You need tcl 8.5 or newer in order to run the Redis testRedis
- tcl/tk參考——系統相關glob
- yymsh - 輕型的類Tcl直譯器
- tcl/tk例項詳解——catch和errorError
- TCL指令碼語言基礎介紹指令碼
- TCL財報:2015年上半年TCL實現營業收入466.84億元 同比增長6.6%
- 02-Tcl輸出、賦值與替換賦值
- 【學習】SQL基礎-011-TCLSQL
- tcl/tk例項詳解——glob使用例解
- 一道TCL的筆試題---遞迴筆試遞迴
- TCL成功“復活”黑莓:還要做平板和智慧穿戴
- 思科聯TCL進軍中國雲端計算市場
- 兩大巨頭打造 TCL愛奇藝智慧電視評測
- 學習tcl的幾個好網路連線