1-TCL语言入门

概述

如何启动TCL

Linux系统:

  • 输入tclsh
  • 在文本第一行 #! /user/bin/tclsh (TCL的安装路径)

Windows系统:

  • 安装active tcl并双击wish.exe

置换

TCL 解释器运用规则把命令分成一个个独立的单词,同时进行必要的置换。

TCL置换分为以下三类:

  • 变量置换 $
  • 命令置换 []
  • 反斜杠置换 \

变量值换

$后面为变量名,将变量置换成它的值。

命令置换

用[]表示命令置换,[]内是一个独立的TCL语句。

反斜杠置换

用\表示反斜杠置换,换行符、空格、[、$等被TCL解释器当作特殊符号对待的字符, 加上反斜杠后变成普通字符

  • 用\t表示TAB。

  • 用\n表示换行符。

其他符号

  • “ ” TCL解释器对双引号中$和[]符号会进行变量置换和命令置换。
  • {} 而在花括号中,所有特殊字符都将成为普通字符,TCL解释器不会对其作特殊处理。
  • # 表示注释。

变量、数组、列表

变量

  • 变量就是某个容器的名称,可以存储一个值。变量的名称在程序运行期间保持不变,但是变量的值通常会不断改变。
  • 定义:set 变量名 变量值
  • 取值:$变量名

例题:假设我们想打印变量varible,后面跟一个”_1”,会发生什么呢?

数组

  • TCL中数组可以存储很多值,通过元素名来进行检索。

  • 定义:set 数组名(元素名) 值

  • 取值:$数组名(元素名)

  • 使用array指令获取数组信息

列表

  • 列表是标量的有序集合。
  • 定义 set 列表名 {元素1 元素2 元素3……}
  • 取值 $列表名

列表操作命令

列表指令-concat

  • 语法格式: concat 列表1 列表2
  • 功能:将列表1和列表2合并

列表指令-llength

  • 语法格式: llength 列表
  • 功能:返回列表中的元素个数

例题: list1为{bufx1 bufx2 bufx4},那么 llength [concat $list1 $list1] 会得到多少呢?

列表指令-lindex

  • 语法格式: lindex 列表 n
  • 功能:返回列表中第n个元素(从0开始计数)

例题:如何得到列表list1 {a b c d e f}的最后一个元素?

列表指令-lappend

  • 语法格式:lappend 列表 新元素
  • 功能: 列表末尾加入新元素

例题:如果我们lappend一个列表会怎么样?如果我们想得到4 用什么样的命令?

列表指令-lsort

  • 语法格式: lsort 开关列表
  • 功能:将列表按照一定规则排序
  • 开关: 缺省时默认按照ASCII码进行排序。

    • –real 按照浮点数值大小排序
    • -unique 唯一化,删除重复元素

例题:如何得到列表list1 {0 1.2 -4 3 5}中的最小值?

数学运算指令-expr

  • 语法格式: expr 运算表达式
  • 功能:将运算表达式求值

例题:我们在TCL中经常会遇到下面的现象

其原因是表达式5/2中5和2都是整数型参数,默认运算结果也是整数型。 如果想要进行浮点运算,只要将其中任意一个数值,写成浮点形式(有小数点)即可

控制流

控制流-if

  • 语法格式:

注意,上例中脚本语句的’{‘一定要写在上一行,因为如果不这样,TCL 解释 器会认为if命令在换行符处已结束,下一行会被当成新的命令,从而导致错误

例题:我们如何判断一个列表{0 1 2 3 4}的长度是大于3,还是等3,还是小于3?

循环指令-foreach

  • 语法格式:foreach 变量 列表 循环主体
  • 功能:从第0个元素开始,每次按顺序取得列表的一个元素,将其赋值给变量,然后执行循环主体一次,直到列表最后一个元素

循环控制指令-break

  • 语法格式:break
  • 功能: 结束整个循环过程,并从循环中跳出

循环控制指令-continue

  • 语法格式:continue
  • 功能:仅结束本次循环

循环控制指令-while

  • 语法格式:while 判断语句 循环主体
  • 功能:如果判断语句成立(返回值非0),就运行脚本,直到不满足判断条件停止循环,此时while命令终端并返回一个空字符串

循环控制指令-for

  • 语法格式:for 参数初始化 判断语句 重新初始化参数 循环主体
  • 功能:如果判断语句返回值非0进入循环,执行循环主体后,再重新初始化参数。然后再次判断,直到判断语句返回值为0,循环结束

过程函数

过程函数-proc

  • 语法格式:proc 函数名 参数列表 函数主体
  • 功能:类似C语言中的函数。即用户自定义的功能,方便多次调用

全局变量与局部变量

  • 全局变量:在所有过程之外定义的变量
  • 局部变量:在过程中定义的变量,只能在过程中访问,退出过程会被自动删除
  • 指令global,在过程内部引用全局变量

正则匹配

  • 定义:正则表达式是一种特殊的字符串模式,用来匹配符合规则的字符串
  • 正则表达式的\w,用来匹配一个字母、数字、下划线
  • 正则表达式的\d,用来匹配一个数字

正则匹配-量词

  • \w\w\w\d\d\d这种写法过于繁琐,可以使用量词表示,常用量词有三种

  • *+的区别:*可以是零次,+一个至少是一次

  • 表示零次或者一次匹配。

正则匹配-锚位

  • 锚位,用来指示字符串中的开头和结尾的位置,使我们能够匹配到正确的字符

正则匹配-其他字符

  • 常用的其他字符还有\s.
  • \s表示空格

  • . 表示任意一个字符,不确定具体使什么字符就可以用.表示。例如已知字符串为”XXX空格XXX空格XXX”(X为未知字符)。用.+\s.+\s.+就可以匹配

正则匹配指令-regexp

  • 语法格式:regexp? switches? exp string? matchVar? ?subMatchVar subMatchVar …?

  • 功能:在字符串中使用正则表达式匹配

  • switches:-nocase将字符串的大写都看成小写

  • exp 正则表达式

  • string 用来表示进行匹配的字符串

  • matchstring表示用正则表达式匹配的所有字符串

  • sub1表示正则表达式中的第一个子表达式匹配的字符串

  • sub2表示正则表达式中的第一个子表达式匹配的字符串

实例讲解

例题:如何匹配字符串”abc456”

例题:如何匹配一个以数字开头并且以数字结尾的字符串?

捕获变量

  • 通过()可以捕获字符串

例:如何将字符串“Snow is 30 years old”中30捕获出来?

  • 一次捕获多个字符串

例:如何将字符串“Snow is 30 years old”中Snow 和30一次捕获?

文本处理

主要掌握三个指令open、gets、close

  • open

    • 语法格式 open 文件 打开方式(r读,w写)
    • 功能 打开文件
  • gets

    • 语法格式 gets fileid 变量名
    • 功能 gets读fileid标识的文件的像遗憾,并把该行赋给变量,并返回该行的字符数(文件尾返回-1)
  • close

    • 语法格式 close fileid
    • 功能 关闭文件

实例讲解

  • 读入整个文件过程

  • 一个完整写入文件过程

例题:现有文本file.txt其内容如下。请写一TCL脚本求出所有Slack值之和。

1
set sum 0
2
set INPUTFILE [open file.txt r]
3
while {[gets $INPUTFILE line] >=0} {
4
if {[regexp {^Slack\s+=\s+(-\d+\.\d+)} $line total slack]} {
5
set sum [expr $sum + $slack]
6
}
7
}
8
close $INPUTFILE
9
puts "The sum of slack is $sum"