TCL命令

Augusdi發表於2015-10-13

TCL命令集合

eval命令本身使用非常簡單,但是用處非常大,如果需要動態的構造命令,那麼必須使用eval命令。

eval命令參考:http://blog.csdn.net/dulixin/archive/2008/03/27/2223978.aspx


    命令格式:eval arg ?arg ...?
    如果是一個引數,那麼相當於把這個引數當作命令來執行,如果有多個引數,eval命令會把多個引數以concat命令風格連線起來然後再執行命令。<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>


    舉一個最簡單的例子:<wbr><wbr><wbr><wbr>
    % set cmd "puts /"This is a tcltk example/""
    puts "This is a tcltk example"
    % eval $cmd
    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>
    % set a puts
    puts
    % set b stdout
    stdout
    % set c "haha"
    haha
    % eval $a $b $c
    haha

<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
catch命令可以用來捕獲一個錯誤,一個沒有捕獲的錯誤將終止指令碼的執行。error會產生一個錯誤,error命令產生的錯誤如果沒有被catch捕獲將會導致指令碼的終止。
    catch命令格式:catch script ?resultVarName? ?optionsVarName?<wbr><wbr><wbr><wbr>
    error命令格式:error message ?info? ?code?
    下面舉一個常用的例子來解釋error和catch是怎麼一起使用的,對其可選項中的各種用途不加詳細解釋。<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
    % proc myError {} {
        error "This is a error"
    }
    % catch myError errorValue
    1
    % puts $errorValue
    This is a error



<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
foreach迴圈,格式為:
    foreach varname list body<wbr><wbr><wbr><wbr>
    foreach varlist1 list1 ?varlist2 list2 ...? body<wbr><wbr><wbr><wbr>
    主要功能為遍歷列表中的元素。<wbr><wbr><wbr><wbr>
    主要有三種使用形式,最簡單的,對單個列表中的元素進行一個一個的遍歷:<wbr><wbr><wbr><wbr>
    % foreach var {a b c d e f} {
    puts $var
    }
    a
    b
    c
    d
    e
    f<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
<wbr><wbr><wbr>
    可以對列表進行多個元素一起賦值,這時varname是一個n個元素列表結構,每次遍歷list列表中的n個元素賦值給以varname列表元素為名稱的變數。<wbr><wbr><wbr><wbr>
    % foreach {var1 var2 var3} {a b c d e f} {
    puts "$var1 $var2 $var3"
    }
    a b c
    d e f<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
<wbr><wbr><wbr>
    遍歷多個列表中的元素,這裡舉例以varname為單個元素為例:<wbr><wbr><wbr><wbr>
    % foreach var1 {a b c} var2 {d e f} {
    puts "$var1 $var2"
    }
    a d
    b e
    c f<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
<wbr><wbr><wbr>
    如果元素不足那麼會以空來補充:<wbr><wbr><wbr><wbr>
    % foreach var1 {a b c} var2 {d e} {
    puts "$var1 $var2"
    }
    a d
    b e
    c<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
<wbr><wbr><wbr><wbr>
    可以利用這個技巧給變數賦值,比如把一個列表中的前3個元素分別賦值給var1、var2和var3:<wbr><wbr><wbr><wbr>
    % foreach {var1 var2 var3} {a b c d e f} {
    break;
    }<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
<wbr><wbr><wbr><wbr>
    % puts "$var1 $var2 $var3"
    a b c<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
    仔細體會一下break的妙用吧。


after有幾種形式,使用比較靈活。
    最簡單的形式,間隔一定時間後再執行指令碼:<wbr><wbr><wbr><wbr>
    % after 5000<wbr><wbr><wbr><wbr>
    上面的命令就是間隔5秒鐘後再繼續執行指令碼,這在等待其它裝置處理時比較有效。<wbr><wbr><wbr><wbr>
    <wbr><wbr><wbr><wbr>
    間隔一段時間後執行一條命令:   <wbr><wbr><wbr><wbr><wbr><wbr><wbr>
    % set a a
    a
    % after 5000 set a b
    after#1<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
<wbr><wbr><wbr><wbr>
    間隔5秒鐘後執行命令set a b,如果等待5秒鐘後再檢視$a的值就變成b了。需要注意的是,在tcl中,時間迴圈並沒有開啟,而tk中事件迴圈總是活動的,所以在tcl指令碼中使用時需要非常小心,可能你需要的值在5秒鐘後並沒有改變,這裡就需要使用到兩個命令update和vwait,update命令可以時直譯器去處理掛起的事件,vwait可以等待一個變數到修改為止,下面舉例說明:<wbr><wbr><wbr><wbr>
    如果在5秒鐘之後使用檢視變數a裡面的值:<wbr><wbr><wbr><wbr>
    % puts $a
    a<wbr><wbr><wbr><wbr>
<wbr><wbr><wbr><wbr>
    還是a,並沒有修改為b,那麼這個時候使用update:<wbr><wbr><wbr><wbr>
    % update
    % puts $a
    b<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
<wbr><wbr><wbr><wbr>
    上面的方法可能在實際使用時並沒有意義,也許指令碼的編寫者是想在tcl中精確的控制指令碼的執行時間,那也沒有問題,可以使用vwait來操作,在時間間隔的期限內使用vwait可以使命令在精確的時間間隔時執行:<wbr><wbr><wbr><wbr>
    % set a a
    a
    % after 5000 set a b
    after#1<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
<wbr><wbr><wbr><wbr>
    % vwait a
    %<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
    會等待到第5秒鐘執行賦值命令。<wbr><wbr><wbr><wbr>
 <wbr>
 <wbr>
    如果註冊了一條命令在某個時間執行,也可以取消這個命令的執行,使用after cancel命令,這個命令有兩種形式,既可以輸入要取消命令的ID,也可以使用該命令本身來取消。<wbr><wbr><wbr><wbr>
    如想要取消ID為after#1的命令:<wbr><wbr><wbr><wbr>
    % after cancel after#1<wbr><wbr><wbr><wbr>
    如果ID為after#1的命令存在就去掉這個命令的註冊,如果不存在就什麼都不發生。<wbr><wbr><wbr><wbr>
    取消一個命令體:<wbr><wbr><wbr><wbr>
    % after 5000 set a c
    after#2    <wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
<wbr><wbr><wbr><wbr>
    % after cancel set a c<wbr><wbr><wbr><wbr>
    以上命令就會取消set a c的事件註冊,如果不存在這個命令就什麼都不發生。<wbr><wbr><wbr><wbr>
 <wbr>
    顯示目前註冊的after事件或者某個after事件的詳細資訊:<wbr><wbr><wbr><wbr>
    直接使用after info命令來顯示所有的after事件:<wbr><wbr><wbr><wbr>
    % after 5000 set a b
    after#1<wbr><wbr><wbr><wbr>
<wbr><wbr><wbr><wbr>
    % after 5000 set a c
    after#2<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
    % after info
    after#2 after#1<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
    如果需要知道after事件的詳細資訊,就需要使用具體的事件ID:<wbr><wbr><wbr><wbr>
    % after info after#1<wbr><wbr><wbr><wbr>
    {set a b} timer

<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必須符合陣列的要求,宣告過變數後,陣列中的元素可以使用setarray命令來配置。

示例

在名字空間中建立一個變數:
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名令,如果level1或者#2或者忽略掉,這個命令將在b的變數的作用域中執行,如果level2或者#1,那麼這個命令將在a的變數的作用域中執行,如果level3或者#0,這個命令將在最高層執行(只有全域性變數是可見的)。

uplevel命令導致在呼叫過程的堆疊層中"看不到"過程了,在下面的例子裡,假設c呼叫命令:

uplevel 1 {set x 43; d}

當d是另外一個過程時,set命令會在b的作用域中修改變數xd將在第三層堆疊執行,就像是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
 }
 }
}
<wbr><wbr><wbr><wbr>
<wbr><wbr><wbr><wbr>
<wbr><wbr><wbr><wbr>


array - 處理陣列變數

語法

array option arrayName ?arg arg ...?

描述

這個命令執行幾種可選項中的一個操作,操作的物件為arrayName,除非以下的命令特殊宣告,否則arrayName必須是存在的陣列變數名稱。option變元決定了要對陣列變數進行什麼樣的操作,具體如下:

array anymore arrayName searchId
如果在一次陣列搜尋當中陣列中還有剩餘的元素就返回1,如果沒有剩餘的元素就返回0searchId指定了被檢查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 matchregexp。如果不指定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 nextelementarray donesearch中使用來標示操作的搜尋,通過使用搜尋標示符允許對一個陣列同時進行不同的搜尋。目前,普遍使用的方式是使用array getarray namesforeach一起使用來遍歷陣列中的每一個元素。具體請參考下面的示例。
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>
    list ?arg arg ...?
    concat ?arg arg ...?
    使用多個arg來組成一個列表,這兩個命令使用頻度很高,使用也非常簡單,所需要注意的地方就是list和concat的區別,以下使用具體的例子來說明兩個命令的區別。
    % list This is a tcltk example
    This is a tcltk example
    % concat 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>
    以上的例子並沒有看出兩個命令有什麼區別,在這種情況下兩個命令的結果並沒有什麼區別,兩個命令的區別主要是list把後面的引數都當作列表的一個元素看待,形成的列表為所有的元素組成,而concat把後面的引數當作一個列表來看待,形成的列表為所有列表中的元素組成。如果兩個命令後面的引數有列表變數就可以看出區別了:
    % list {This is} {a} {tcltk example}
    {This is} a {tcltk example}
    % concat {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>

    concat可以形象地說是去掉了一層列表結構,然後再list所有的元素。使用時需要注意兩者的卻別。<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
 <wbr>
    lrepeat number element1 ?element2 element3 ...?
使用重複的元素構建列表,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>
    join list ?joinString?
    split string ?splitChars?
    這兩個命令為一對相反的命令,它們操作的過程都為對方的逆過程。join命令把一個列表中的元素使用joinString連線成一個字串,而split是根據splitChars把一個字串分割為列表。如果沒有後面的可選變元,分割符預設為空白符。如下例:
    % join {This is a tcltk example} ?
    This?is?a?tcltk?example
    % split 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>
    第二個命令使用第一個命令的結果作為引數。


 列表操作在指令碼中使用的頻率非常高,基本上每個指令碼都會涉及到其中的一些操作,在這裡對列表的命令進行例項解析,以加深對列表命令的理解,本文涉及的命令為llength、lindex、lrange、lsearch和lassign。
 <wbr>
    llength list
    返回一個列表的元素個數,非常簡單而又常用的命令。
    % llength {This is a tcltk example}
    5<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
 <wbr>
    lindex list ?index...?
    根據索引值,找出列表中索引為index的元素,如果沒有index就返回整個列表,如果有多個index就返回列表的子列表的元素,具體示例如下:
    返回整個列表:
    % lindex {This is a tcltk example}
    This is a tcltk example<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>

    返回列表中索引為3的元素:
    % lindex {This is a tcltk example} 3
    tcltk
<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
    返回列表中索引為2的元素
    % lindex {{This is} a {tcltk example}} 2
    tcltk example
<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
    返回列表中索引為2的子列表中索引為1的元素
    % lindex {{This is} a {tcltk example}} 2 1
    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>
    lrange list first last
    返回列表一個區間的元素,這個區間由first和last指定。
    % lrange {This is a tcltk example} 1 3
    is a tcltk<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
 <wbr>
    lsearch ?options? list pattern
    在列表中尋找元素,這裡的標誌位比較多,下面一一介紹,多個標誌位可以互相混用。
    以下是匹配風格標誌位:
    尋找的列表元素嚴格匹配pattern,也就是說pattern就是列表中的一個元素才能找到,返回元素的索引:
    % lsearch -exact {This is a tcltk example} is
    1
<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
    以glob風格匹配pattern,沒有匹配風格標誌位的話預設就是glob,搜尋以is結尾的字元:
    % lsearch -glob {This is a tcltk example} *is
    0
<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
    以正規表示式風格匹配,搜尋以is結尾的字元:
    % lsearch -regexp {This is a tcltk example} .*is
    0
<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
    以下是一些修飾標誌位:
    返回所有符合匹配風格的元素索引:
    % lsearch -all {This is a tcltk example} *is
    0 1
<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
    返回符合匹配風格的元素值而不是索引:
    % lsearch -inline -all {This is a tcltk example} *is
    This is
<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
    返回不符合匹配風格的元素索引:
    % lsearch -not -all {This is a tcltk example} *is
    2 3 4
<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
    從指定的索引開始搜尋,下面的例子只返回了索引1,沒有返回索引0:
    % lsearch -start 1 -all {This is a tcltk example} *is
    1
<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
    內容描述標誌位:
    所匹配的內容為ASCII碼,使用-ascii標誌位,預設就是。
    可以和-sorted一起使用-dictionary來標誌以字典順序匹配。
    使用-integer說明列表元素被當作整數匹配。
    -real說明列表元素被當作浮點數匹配。
    -nocase忽略大小寫:
    % lsearch -nocase {This is a tcltk example} this
    0
<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
    還有兩個排序標誌位,需要和sorted一起使用,-decreasing和-increasing分別代表降序和升序。
兩個嵌入式標誌位:
    -index,匹配子列表中的索引,下面的例子匹配子列表中的第二個元素,有這個標誌位要求list中每個元素都必須有子列表,並且有需要檢查的index:
    % lsearch -index 1 -all {{This is} {b  a} {tcltk example}} *a*
    1 2
<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
    -subindices,需要和-index一起使用,返回匹配的全路徑:
    % lsearch -index 1 -all -subindices {{This is} {b  a} {tcltk example}} *a*
    {1 1} {2 1}<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
 <wbr>
    lassign list varName ?varName ...?
    將列表元素賦值給變數,直接採用help裡面的例子,非常明確了:
    lassign {a b c} x y z       ;# 返回空
    puts $x                     ;# Prints "a"
    puts $y                     ;# Prints "b"
    puts $z                     ;# Prints "c"<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
 <wbr>
    lassign {d e} x y z         ;# 返回空
    puts $x                     ;# Prints "d"
    puts $y                     ;# Prints "e"
    puts $z                     ;# Prints ""<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
 <wbr>
    lassign {f g h i} x y       ;# 返回"h i"
    puts $x                     ;# Prints "f"
    puts $y                     ;# Prints "g"


<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
列表操作在指令碼中使用的頻率非常高,基本上每個指令碼都會涉及到其中的一些操作,在這裡對列表的命令進行例項解析,以加深對列表命令的理解,本文涉及的命令為lappend、lreplace、lset、linsert、lsort和lreverse。
 <wbr>
    lappend varName ?value value value ...?
    在列表後面新增元素,常用的命令,lappend命令接收一個變數名(這裡需要注意,必須是變數名而不是變數),將元素新增到變數後面,變數會被修改:
    % set myList {This is a}
    This is a
    % lappend myList tcltk example
    This is a tcltk example
    % puts $myList
    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>
    由以上可以看出,變數myList已經被修改了,在tcl中如果命令中傳入的是變數名一般結果都修改變數,傳入的是變數值都不會修改變數本身。<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
 <wbr>
    lreplace list first last ?element element ...?
    將索引為first到last的元素替換為後面的元素:
    % lreplace {This is a tcltk example} 2 2 another
    This is another tcltk example
    % lreplace {This is a tcltk example} 2 3 another TCLTK
    This is another 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>
    lset varName ?index...? newValue
    這個命令和lappand一樣接收一個變數名作為引數,也會修改變數的值,將列表中的指定索引專案修改為指定值,如果不指定索引項就把列表整個換為新的值:
    % set myList {This is a tcltk example}
    This is a tcltk example
    % lset myList 2 another
    This is another tcltk example
    % puts $myList
<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
    This is another tcltk example<wbr><wbr><wbr><wbr>
    如果沒有指定索引,就相當於直接賦值:
    % lset myList {no index}
    no index<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
 <wbr>
    linsert list index element ?element element ...?
    這個命令插入元素到列表的index索引位,產生一個新的列表:
    % linsert {This is example} 2 a tcltk
    This is a tcltk example<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
 <wbr>
    lsort ?options? list 
    為列表排序。
    按照ASCII碼順序排序,這個是預設狀態:
    % lsort -ascii {b A c B a C}
    A B C a b c
<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
    按照字典順序排序:
    % lsort -dictionary {b A c B a C}
    A a B b C c<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>

    按照整數排序,要求列表裡面的元素都能正確轉化為整數:
    % lsort -integer {11 13 15 56}
    11 13 15 56
<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
    按照浮點數排序,要求列表裡面的元素都能夠正確轉化為浮點數:
    % lsort -real {11.1 22.2 14.3}
    11.1 14.3 22.2
<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
    按照命令排序,命令體必須是接收兩個引數的命令,結果返回大於、小於或者等於0分別代表兩個元素相比較是大於、小於還是等於關係,利用此關係進行排序:
    % lsort -command {string compare}  {b A c B a C}
    A B C a b c
<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
    按照升序排列,這是預設形式:
    % lsort -increasing {b A c B a C}
    A B C a b c
<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
    按照降序排列:
    % lsort -decreasing {b A c B a C}
    c b a C B A
<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
    返回排序後的元素在原列表中的索引:
    % lsort -indices {b A c B a C}
    1 3 5 4 0 2
<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
    根據子列表排序,每個元素必須是一個命令能夠正確識別的子列表,-index 1表示根據子列表的第二個元素來排序:
    % lsort -index 1 {{b A} {c B} {a C}}
    {b A} {c B} {a C}
<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
    忽略大小寫:
    % lsort -nocase {b A c B a C}
    A a b B c C<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
 <wbr>
    lreverse list
    返回一個列表,列表為原列表的反序形式:
    % lreverse {This is a tcltk example}
    example tcltk a is This
<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>
<wbr><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  <wbr> a b {c  <wbr><wbr> “ d “  <wbr><wbr> e} f”


會返回“a b {c d e} f”。


注意,並置不會刪除引數間的空白,所以命令:

concat “a   <wbr><wbr><wbr> b   <wbr><wbr><wbr> c” { d e f}


會返回“a   <wbr><wbr><wbr> b   <wbr><wbr><wbr> c d e f”(abc之間有三個空格)。



join list ?joinString?


把列表的元素連線起來而建立一個字串。引數list必須是效的Tcl列表。此命令返回格式化後的字串(把列表list的所有元素用字串joinString連線相鄰的元素而構成)。引數joinString預設為是一個空格字元。


例子:


用逗號分隔列表的元素:

set data {1 2 3 4 5}

join $data ", "


    <wbr><wbr><wbr><wbr> 1, 2, 3, 4, 5


使用join去展平列表為單層的列表:

set data {1 {2 3} 4 {5 {6 7} 8}}

join $data


    <wbr><wbr><wbr><wbr> 1 2 3 4 5 {6 7} 8


lappend varName ?value value value …?


把值新增到列表中。此命令把變數varName視為列表,並且把每個引數value作為單獨的元素新增到列表varName的值中,每個元素用空格分隔。如果varName不存在,則被建立為列表,而其值就是引數valuelappendappend相似,除了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的個數多,則此命令返回沒有被賦給變數的元素。 <wbr>


例子:


下面的例子說明了是怎樣多重賦值的,和當如果太少或太多元素會發生什麼:

lassign {a b c} x y z      <wbr><wbr><wbr><wbr><wbr><wbr> ;# Empty return

puts $x       <wbr><wbr><wbr><wbr><wbr><wbr><wbr>              <wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>;# Prints "a"

puts $y                    <wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr> ;# Prints "b"

puts $z                    <wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr> ;# Prints "c" <wbr>


lassign {d e} x y z        <wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr> ;# Empty return

puts $x                    <wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr> ;# Prints "d"

puts $y                    <wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr> ;# Prints "e"

puts $z        <wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>             <wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>;# Prints ""


lassign {f g h i} x y      <wbr><wbr><wbr><wbr><wbr><wbr> ;# Returns "h i"

puts $x                    <wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr> ;# Prints "f"

puts $y                    <wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr> ;# Prints "g"


lassign命令也有其它的用法。它可以用於建立類似於其它shell語的“shift”命令:

set ::argv [lassign $::argv argumentToReadOff] <wbr>


lindex list ?index …?


檢索列表中的元素。索引可以在命令列連續地提交,或組合為一個列表作為單個引數提交。如果沒有提供索引,則命令採取的形式為:

lindex list <wbr>  <wbr> lindex list {}


在此情況中,lindex的返回值就是引數list的值。


當只提供單個索引時,lindex命令返回列表中第index個元素(列表元素的索引從0開始計算)。在提取元素時,lindex遵守大括號,雙引號和反斜槓的規則;但,不會發生變數替換和命令替換。如果index是一個負數或者是大於或等於元素的數量,則返回一個字串。對每個簡單的index值的解釋,與命令string index相同,支援簡單的索引算術運算和相對於列表尾端的索引(用end表示列表的尾端)。


如果提供額外的引數index,則每個引數依次選取一個元素,允許指令碼從子列表中選取元素。命令:

lidnex $a 1 2 3 <wbr>  <wbr> lindex $a {1 2 3}


等同於:

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


例子:

列表可以從兩端索引:

lindex {a b c} 0

     <wbr><wbr><wbr><wbr><wbr> → a


lindex {a b c} 2

     <wbr><wbr><wbr><wbr><wbr> → c


lindex {a b c} end

     <wbr><wbr><wbr><wbr><wbr> → c


lindex {a b c} end-1

     <wbr><wbr><wbr><wbr><wbr> → b


列表或索引的序列可以從列表中的列表選取元素:

lindex {a b c}

     <wbr><wbr><wbr><wbr><wbr> → a b c


lindex {a b c} {}

     <wbr><wbr><wbr><wbr><wbr> → a b c


lindex {{a b c} {d e f} {g h i}} 2 1

     <wbr><wbr><wbr><wbr><wbr> → h


lindex {{a b c} {d e f} {g h i}} {2 1}

     <wbr><wbr><wbr><wbr><wbr> → h


lindex {{{a b} {c d}} {{e f} {g h}}} 1 1 0

     <wbr><wbr><wbr><wbr><wbr> → g


lindex {{{a b} {c d}} {{e f} {g h}}} {1 1 0}

     <wbr><wbr><wbr><wbr><wbr> → g


列表索引也可以執行有限的計算,從其它索引中相加或減去固定的數量:

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”

   <wbr><wbr><wbr> à 0 1 hello 2 3 4 5


把一些值放入一個列表中,首先從開頭索引,然後從尾端索引,然後將他們連結一起:

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 <wbr>  <wbr>" " <wbr>  <wbr>f {g h}"

會返回

a b {c d e <wbr> } { <wbr> f {g h}}


而相同引數的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中的firstlast的元素組成(包括firstlast的元素)。對索引值firstlast的解釋與命令string index的索引值相同,支援簡單的索引算術運算和相對於列表尾端的索引(用end表示列表的尾端)。如果first小於0,則它被視為0。如果last大於或等於list的元素數量,則它被視為是end。如果firstlast大,則返回一個空字串。注意,“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

     <wbr><wbr><wbr><wbr><wbr> → a a a


lrepeat 3 [lrepeat 3 0]

     <wbr><wbr><wbr><wbr><wbr> → {0 0 0} {0 0 0} {0 0 0}


lrepeat 3 a b c

     <wbr><wbr><wbr><wbr><wbr> → a b c a b c a b c


lrepeat 3 [lrepeat 2 a] b c

     <wbr><wbr><wbr><wbr><wbr> → {a a} b c {a a} b c {a a} b c


lreplace list first last ?element element…?


lreplace返回一個新列表,通過用引數element代替一個或多個list的元素而形成的新列表。索引值firstlast指定了代替範圍的第一個和最後一個元素。對索引值firstlast的解釋與命令string index的索引值相同,支援簡單的索引算術運算和相對於列表尾端的索引(用end表示列表的尾端)。0表示列表的第一個元素,而end表示列表的最後一個元素。如果list為空,則忽略firstlast


如果first小於0,則它被視為指向列表第一個元素的前面。對於非空列表,first指示的元素必須存在,或者first必須指向列表的開頭。


如果last小於first,則任何指定的元素都會被插入到由first指定的位置中,而沒有元素被刪除。


引數element指定了零個或多個新的引數,新增到列表中那些已被刪除的元素的位置處。每個引數element將成為一個單獨的列表元素。如果沒有指定引數element,則firstlast間的元素只是簡單地被刪除。如果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} {

   <wbr><wbr><wbr> upvar 1 $listVariable var

  <wbr><wbr>  <wbr>set idx [lsearch -exact $var $value]

   <wbr><wbr><wbr> set var [lreplace $var $idx $idx]

}


lreverse list


此命令返回一個列表,其元素與列表list相同,但元素的順序相反。


例子:

lreverse {a a b c}

     <wbr><wbr><wbr><wbr><wbr> → c b a a

lreverse {a b {c d} e f}

     <wbr><wbr><wbr><wbr><wbr> → f e {c d} b a


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給出了在每個元素中的索引的路徑(可能與lindexlset命令聯用),以允許被匹配的術語的位置。


-subindices

如果給出了此選項,此命令的索引結果(或者當也指定了-all時,每個索引結果)將是在整個列表內找到的專案的完整的路徑(適用於與lindexlset聯用)。除非也指定了-index,否則此選項沒有效果,它只是一個方便的快捷方式。


例子:

基本的搜尋:

lsearch {a b c d e} c

     <wbr><wbr><wbr><wbr><wbr> 2


lsearch -all {a b c a b c} c

     <wbr><wbr><wbr><wbr><wbr> 2 5


使用lsearch過濾列表:

lsearch -inline {a20 b35 c47} b*

     <wbr><wbr><wbr><wbr><wbr> b35


lsearch -inline -not {a20 b35 c47} b*

     <wbr><wbr><wbr><wbr><wbr> a20


lsearch -all -inline -not {a20 b35 c47} b*

     <wbr><wbr><wbr><wbr><wbr> a20 c47


lsearch -all -not {a20 b35 c47} b*

     <wbr><wbr><wbr><wbr><wbr> 0 2


甚至可以執行“set-like”的刪除操作:

lsearch -all -inline -not -exact {a b c a d e a f g a} a

     <wbr><wbr><wbr><wbr><wbr> b c d e f g


Searching may start part-way through the list:

可以用部分的方式開始搜尋整個列表:

lsearch -start 3 {a b c a b c} c

     <wbr><wbr><wbr><wbr><wbr> 5


也可以搜尋內部的元素:

lsearch -index 1 -all -inline {{a abc} {b bcd} {c cde}} *bc*

     <wbr><wbr><wbr><wbr><wbr> {a abc} {b bcd}


lset varName ?index ...? newValue


更改列表中的元素。varName它是一個Tcl列表。索引可以在命令列連續的提供或組合為一個列表作為單個引數提供。newValue是列表narName中某一元素的新值。如果沒有提供索引,則命令的形式為:

lset varName newValue

lset varName {} newValue


在這種情況中,newValue代替變數varName的舊值。

    當只提供一個索引時,它定址列表varName中第index個元素。當作列表解釋的varNamelset遵守有關作為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]]

     <wbr><wbr><wbr><wbr><wbr> {a b c} {d e f} {g h i}


下列每個命令的返回值也成為了x的新值(除了最後一個命令外,它發生錯誤,而x的值不變)

lset x {j k l}

     <wbr><wbr><wbr><wbr><wbr> j k l


lset x {} {j k l}

 <wbr>     <wbr><wbr><wbr><wbr>j k l


lset x 0 j

     <wbr><wbr><wbr><wbr><wbr> j {d e f} {g h i}


lset x 2 j

     <wbr><wbr><wbr><wbr><wbr> {a b c} {d e f} j


lset x end j

     <wbr><wbr><wbr><wbr><wbr> {a b c} {d e f} j


lset x end-1 j

     <wbr><wbr><wbr><wbr><wbr> {a b c} j {g h i}


lset x 2 1 j

     <wbr><wbr><wbr><wbr><wbr> {a b c} {d e f} {g j i}


lset x {2 1} j

     <wbr><wbr><wbr><wbr><wbr> {a b c} {d e f} {g j i}


lset x {2 3} j

     <wbr><wbr><wbr><wbr><wbr> list index out of range


在下列例子中,x的初始值為:


set x [list [list [list a b] [list c d]] \

           <wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr> [list [list e f] [list g h]]]

     <wbr><wbr><wbr><wbr><wbr> {{a b} {c d}} {{e f} {g h}}


指示返回值也將成為 x 的新值。

lset x 1 1 0 j

     <wbr><wbr><wbr><wbr><wbr> {{a b} {c d}} {{e f} {j h}}


lset x {1 1 0} j

     <wbr><wbr><wbr><wbr><wbr> {{a b} {c d}} {{e f} {j h}}


lsort ?options? list


排序列表的元素。此命令排序列表list的元素,返回一個按順序排序的新列表。lsort命令的實現使用一個穩定排序具有O(n log n)效能特徵的合併排序演算法。


預設使用ASCII排序,結果以升序返回。然而,在列表list的前面,可以指定下列任何的選項,以控制排序的程式(接受唯一的縮寫)

-ascii

使用Unicode碼位排序規則順序(名稱是為了向後相容的原因)比較字串。這是預設選項。


-dictionary

使用字典式的比較。這與-ascii一樣,除了(a)忽略大小寫(tie-breaker關係斷路器除外),(b)如果兩個字串包含有嵌入的數字,數字作為整數比較而不是作為字元。例如,在-dictionary模式中,bigBoy排在bigbangbigboy之間,而x10y排在x9yx11y之間。


-integer

把列表元素轉換成整數並使用整數比較。


-real

把列表元素轉換成浮點數並使用浮點數比較。


-command command

使command作為一個比較命令。要比較兩個元素,評估由命令組成的指令碼,此命令帶有兩個元素作為額外的引數。大如果第一個元素小於,等於,或大於第二個元素,則此本應返回一個小於,等於,或大於0的整數。


-increasing

以升序對列表排序(最小的元素在第一)。這是預設。


-decreasing

以降序對列表排序(最大的元素在第一)


-indices

返回列表中排序的索引,而不是索引對應的值。


-index indexList

如果指定了這個選項,則列表list中的每個元素它自己必須是一個適當的sublist(子列表)(除非使用了-stride)。不是基於整個sublists排序,而是lsort將從每個sublist中提取第 indexList個元素(好像全部的元素和indexList被傳遞給了lindex)並且基於給定的元素排序,例如:


lsort -integer -index 1 \

     <wbr><wbr><wbr><wbr><wbr> {{First 24} {Second 18} {Third 30}}

返回{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} {

  <wbr><wbr> {{b i g} 12345}

  <wbr><wbr> {{d e m o} 34512}

  <wbr><wbr> {{c o d e} 54321}

}

返回{{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忽略)的第一個索引指示的每一組中的元素來排序。在各個組中的元素總是在同一位置。 <wbr>


列表的長度必須是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} {

   <wbr><wbr><wbr> set a0 [lindex $a 0]

   <wbr><wbr><wbr> set b0 [lindex $b 0]

   <wbr><wbr><wbr> if {$a0 < $b0} {

       <wbr><wbr><wbr><wbr><wbr><wbr><wbr> return -1

   <wbr><wbr><wbr> } elseif {$a0 > $b0} {

       <wbr><wbr><wbr><wbr><wbr><wbr><wbr> return 1

   <wbr><wbr><wbr> }

   <wbr><wbr><wbr> return [string compare [lindex $a 1] [lindex $b 1]]

}


% lsort -command compare \

       <wbr><wbr><wbr><wbr><wbr><wbr><wbr> {{3 apple} {0x2 carrot} {1 dingo} {2 banana}}

{1 dingo} {2 banana} {0x2 carrot} {3 apple} <wbr>


split string ?splitChars?


返回一個用引數splitChars中的每個字元折分string而形式的列表。結果列表中的每個元素由string中每個splitChars字元間的字元組成。如果string中包含兩個連續的splitChars字元,則會產生一個空元素,或者string中的第一個字元或最後一個字元是splitChars中的字元,也會產生一個空元素。如果splitChars是空字串,則string中的每個字元成為結果列表中的每個元素。splitChars預設為空格。

例子:

折分USENET組名為各個分層元件:

split "comp.lang.tcl" .

     <wbr><wbr><wbr><wbr><wbr> → comp lang tcl

下面看看是如何用splitChars中的每個字元來折分string的,如果不小心可能會導致遺失某些資訊:


split "alpha beta gamma" "temp"

     <wbr><wbr><wbr><wbr><wbr> → al {ha b} {} {a ga} {} a


從一個格式化得不好列表字串中提取列表的words

split "Example with {unbalanced brace character"

     <wbr><wbr><wbr><wbr><wbr> → Example with \{unbalanced brace character


字串的每個字元成為列表的一個元素:

split "Hello world" {}

     <wbr><wbr><wbr><wbr><wbr> → H e l l o { } w o r l d <wbr>


分析面向記錄的檔案

分析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 {

  <wbr><wbr> ## Split into fields on colons

  <wbr><wbr> set fields [split $rec ":"] <wbr>


  <wbr><wbr> ## Assign fields to variables and print some out...

  <wbr><wbr> lassign $fields \

        <wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr> userName password uid grp longName homeDir shell

  <wbr><wbr> puts "$longName uses [file tail $shell] for a login shell"

}

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 



相關文章