Tool command language(Tcl)
3. 其它有用的Tcl命令
TCAD Sentaurus工具引入更高级的Tcl命令
3.1文件输入和输出
-
使用open函数打开文件:
set FIDw [open Writing.tmp "w"]
这里以写的方式打开文件Writing.tmp。FIDw是一个常规的Tcl变量,它包含文件标识符。
-
使用put 命令写入打开的文件:
puts $FIDw "This is the first line of this file"
puts $FIDw $ABCList
- 使用close命令关闭文件:
close $FIDw
- 以读的方式打开文件
set FIDr [open Writing.tmp "r"]
- gets命令逐行读取文件
while { [gets $FIDr NewLine] > 0 } { #NewLine是固定必须的关键词?
puts $NewLine
}
close $FIDr
#-> This is the first line of this file
#-> a b c d e f
这里,while循环检测文件的结尾。gets命令返回读取的字节数。如果gets到达文件末尾,它将返回-1.while循环将测试此条件。
- 使用read命令将文件作为单个数据块读取
set FIDr [open Writing.tmp "r"]
set DATA [read $FIDr]
puts $DATA
close $FIDr
#-> This is the first line of this file
#-> a b c d e f
包含特殊Tcl字符的文件通常无法逐行读取。read命令没有这些问题。
3.2 格式化输出
使用格式函数控制打印期间变量的格式:
set pi [ expr 2.0*asin(1.0) ]
puts "pi unformated :$pi"
#-> pi unformated: 3.141592
puts "pi with 2 digits :[format %.2f $pi]"
#-> pi with 2 digits : 3.14
puts "pi in exponential format: [format %.4e $pi]"
#-> pi in exponential format: 3.1416e+00
set i 24
puts "Integer with leading zeros: >[format %05d $i]<"
#-> Integer with leading zeros: >00024<
puts "Integer with leading blanks: >[format %5d $i]<"
#-> Integer with leading zeros: > 24<
3.3 程序
自定义一个计算Arrthenius law的程序。A=A0exp(-E/KT),其中 A0是指前因子(频率因子),E是活化能。温度由全局变量T给出。
proc Arrhenius {A0 E} {
global T
set k 8.62e-5; # eV/K
set A [expr $A0*exp(-$E/($k*$T))]
return $A
}
可以在Tcl脚本的任何位置定义过程。但是,只有在定义过程之后才能调用该过程。
set T 300
set A [Arrhenius 1e5 1.0]
puts "The Arrhenius expression given: [format %.4e $A]"
#-> The Arrhenius expression given: 1.6067e-12
3.4 屏蔽特殊字符、替换
美元符号$、括号[]和大括号{}是Tcl中的特殊字符。例如,如果在字符串中使用这些字符,则必须对它们进行掩码,也就是说,它们前面必须有反斜杠()
set T 400.0
set CMD_Static "[Arrhenius 1e5 1.0]"
puts [format "\[Arrhenius 1e5 1.0\] gives %.4e" $CMD_Static]
#-> [Arrhenius 1e5 1.0] gives 2.5378e-08
set T 1100.0
puts [format "\[Arrhenius 1e5 1.0\] gives %.4e" $CMD_Static]
#-> [Arrhenius 1e5 1.0] gives 2.5378e-08
注意,变量CMD_Static包含Arrhenius表达式的值,在定义变量时计算。后面的温度变化对此没有影响。
CME_Static和CMD_Dynamic是关键字??
还有,使用\屏蔽函数调用仅在使用expr命令调用时计算函数Arrhenius
set T 400.0
set CMD_Dynamic "\[Arrhenius 1e5 1.0\]"
puts $CMD_Dynamic
#-> [Arrhenius 1e5 1.0]
puts [format %.4e [expr $CMD_Dynamic]]
#-> 2.5378e-08
set T 1100.0
puts [format %.4e [expr $CMD_Dynamic]]
#-> 2.6291e-08
3.5 文件和目录
-
使用glob函数获取与特定模式匹配的所有文件名的列表:
set FIDw [open Tmp_1.tmp "w"] puts $FIDw "test" close $FIDw set FIDw [open TMP_2.tmp "w"] puts $FIDw "test" close $FIDw set FIELS [glob "TMP"] puts "$FILES" #-> TMP_1.tmp TMP_2.tmp
这里创建了两个文件TMP_1.TMP和TMP_2.TMP. 然后,创建当前工作目录中以TMP开头的所有文件的列表。
-
使用file函数分隔文件名和扩展名
set FILE [lindex $FILES 0] set STEM [file rootname $FILE] puts "The rootname is : $STEM" #-> The rootname is :TMP_1 set EXT [file extension $FILE] puts "The extension is :$EXT" #-> The extension is : .tmp
-
使用pwd命令访问当前工作目录的名称:
set CWD [pwd] puts $CWD
-
使用file函数分隔路径和目录:
set PATH [file dirname $CWD] puts "Path is : $PATH" set DIR [file tail $CWD] puts "Directory is $DIR"
3.6 系统调用
-
使用exec命令发出系统调用
exec rm -f Writing.tmp
这里从Tcl内调用UNIX命令rm -f
-
使用eval命令进行包含Tcl变量的系统调用
set FILE source.tcl eval exec rm -f $FILE
eval 命令强制展开所有Tcl变量和表达式
-
返回数据的系统调用
set ls_output [exec ls] puts "The output of the ls command is:" puts $ls_output
3.7 处理错误
如果发生错误,Tcl将终止脚本的执行。使用catch命令抑制终止:
set Nom 0.0
set Denom 10.0
if { [catch { set result [expr $Denom/$Nom] } Errcode] != 0}
{
puts "An Error occured.The Error code is >$Errcode< "
} else {
puts "$Denom/$Nom = $result"
}
#-> An error occured.The Error code is >divide by zero<
有意的操作是set result [expr $Denom/$Nom],如果此操作失败,catch将抑制脚本的终止,将错误代码分配给变量ErrCode,并返回一个非零值。
3.8 字符操作
举例,假如要处理一个字符串,该字符串包含有关简单结构描述的信息,包括材料名称、区域名称和几何对象(注意,双引号、大括号和方括号必须用反斜杠屏蔽,因为它们在Tcl中具有特定的含义)
set STRING "Silicon \"substrate\" \{ rectangle \[(0.0, -0.5) (1.0, 0.5)\] \}"
-
使用字符串函数隔离材质和区域名称
set itmp [expr [string first " " $STRING]} set MATERIAL [string range $STRING 0 [expr $itmp -1]] set istart [ expr [string first "\"“ $STRING]] set iend [ expr [string last "\"” $STRING]] set REGION [string range $STRING [expr $istart +1 ] [expr $iend -1]] puts "The material is : $MATERIAL" #-> The material is : Silicon puts "The region name is :$Region" #-> The region name is:substrate
函数string first和string last 分别返回给定模式的第一次或最后一次出现的索引,这里是空白或双引号。函数字符串范围返回一个子字符串,它在给定的索引处开始和结束。
坐标X0、Y0、X1和Y1可以以类似的方式提取:set istart [expr [string first "(" $STRING]] set iend [expr [string first "," $STRING]] set X0 [string range $STRING [expr $istart+1] [expr $iend -1]] set istart [expr [string first "," $STRING]] set iend [expr [string first ")" $STRING]] set Y0 [string range $STRING [expr $istart+1] [expr $iend -1]] set istart [expr [string last "(" $STRING]] set iend [expr [string last "," $STRING]] set X1 [string range $STRING [expr $istart+1] [expr $iend -1]] set istart [expr [string last "," $STRING]] set iend [expr [string last ")" $STRING]] set Y1 [string range $STRING [expr $istart+1] [expr $iend -1]]
-
连接两个字符串:
set NewString ${MATERIAL}_${REGION} puts $NewString #-> Silicon_substrate
-
使用append函数将文本附加到字符串:
set Text "$NewString extends from" append Text "X=$X0 to $X1 " append Text "and from" append Text "Y= $Y0 to $Y1." puts $Text #->Silicon_substrate extends from X=0.0 to 1.0 and from Y = -0.5 to 0.5
-
比较字符串(词典编纂)与字符串比较
set NAME1 "Eva" set NAME2 "Adam" if { [string compare $NAME1 $NAME2] == 0} { puts "Both names are the same" } elseif { [string compare $NAME1 $NAME2] <0 } { puts "$NAME1 comes before $NAME2" } elseif { [string compare $NAME1 $NAME2] >0} { puts "$NAME2 comes before $NAME1" } #-> Adam comes before Eva
-
提取字符串匹配的子模式
set DEV "HV NMOStransistor" if { [string match "*NMOS*" $DEV]} { puts "This device is an NMOS" } else { puts "This device is NOT an NMOS" } #-> This device is an NMOS
-
用regsub替换字符串中的模式
set OLDString "HV NMOStransistor" set OLDPattern "NMOS" set NEWPattern "PFET" set NEWString [regsub $OLDPattern $OLDString $NEWPattern] puts "NEWString:$NEWString" #-> NEW String: HV PFETransistor
-
将字符串转换为列表:
Tcl允许将字符串重新解释为列表,只要条目用空格分隔即可set string "1 2 3 4" set SUM 0 foreach Number $String { set SUM [expr $SUM+$Number ] } puts $SUM #->10
如果条目由不同的符号(如逗号分隔值(CSV)分隔,请使用split命令:
set String "1,2,3,4" set List [split $String ","] set SUM 0 foreach Number $List{ set SUM [expr $SUM+$Number] } puts $SUM #->10