if {[regexp $pattern $line]} { puts stdout $line } } close $f }
以上过程非常象UNIX的grep命令, 你可以用两个参数调用它,一个是模式,另一个是文件名,tgrep将打印出文件中所有匹配该模式的行。
下面介绍上述过程中用到的几个基本的文件输入输出命令。 open name ?access?
open命令 以access方式打开文件name。返回供其他命令(gets,close等)使用的文件标识。如果name的第一个字符是“|”,管道命令被触发,而不是打开文件。
文件的打开方式和我们熟悉的C语言类似,有以下方式: r 只读方式打开。文件必须已经存在。这是默认方式。 r+ 读写方式打开,文件必须已经存在。
w 只写方式打开文件,如果文件存在则清空文件内容,否则创建一新的空文件。 w+ 读写方式打开文件,如文件存在则清空文件内容,否则创建新的空文件。 a 只写方式打开文件,文件必须存在,并把指针指向文件尾。
a+ 只读方式打开文件,并把指针指向文件尾。如文件不存在,创建新的空文件。
open命令返回一个字符串用于表识打开的文件。当调用别的命令(如:gets,puts,close,〕对打开的文件进行操作时,就可以使用这个文件标识符。TCL有三个特定的文件标识: stdin,stdout和stderr ,分别对应标准输入、标准输出和错误通道,任何时候你都可以使用这三个文件标识。
gets fileId ?varName? 读fileId标识的文件的下一行,忽略换行符。如果命令中有varName就把该行赋给它,并返回该行的字符数(文件尾返回-1),如果没有varName参数,返回文件的下一行作为命令结果(如果到了文件尾,就返回空字符串)。 和gets类似的命令是read,不过read不是以行为单位的,它有两种形式:
read ?-nonewline? fileId 读并返回fileId标识的文件中所有剩下的字节。如果没有nonewline开关,则在换行符处停止。 read fileId numBytes 在fileId标识的文件中读并返回下一个numbytes字节。
puts ?-nonewline? ?fileId? string puts命令把string写到fileId中,如果没有nonewline开关的话,添加换行符。fileId默认是stdout。命令返回值为一空字符串。
puts命令使用C的标准I/O库的缓冲区方案,这就意味着使用puts产生的信息不会立即出现在目标文件中。如果你想使数据立即出现在文件中,那你就调用flush命令:
flush fileId 把缓冲区内容写到fileId标识的文件中,命令返回值为空字符串。
flush命令迫使缓冲区数据写到文件中。flush直到数据被写完才返回。当文件关闭时缓冲区数据会自动flush。 close ?fileId? 关闭标识为fileId的文件,命令返回值为一空字符串。
这里特别说明的一点是,TCL中对串口、管道、socket等的操作和对文件的操作类似,以上对文件的操作命令同样适用于它们。 文件访问 > 随机文件访问
默认文件输入输出方式是连续的:即每个gets或 read命令返回的是上次gets或 read访问位置后面的字节,每个puts命令写数据是接着上次puts写的位置接着写。TCL提供了seek,tell和eof等命令使用户可以非连续访问文件。
每个打开的打开文件都有访问点,即下次读写开始的位置。文件打开时,访问点总是被设置为文件的开头或结尾,这取决于打开文件时使用的访问模式。每次读写后访问位置按访问的字节数后移相应的位数。 可以使用seek命令来改变文件的访问点:
seek fileId offset ?origin? 把fileId标识的文件的访问点设置为相对于origin偏移量为offset的位置。origin可以是start,current,end,默认是start。命令的返回值是一空字符串。
例如:seek fileId 2000 改变fieleId标识的文件访问点,以便下次读写开始于文件的第2000个字节。
seek的第三个参数说明偏移量从哪开始计算。第三个参数必为start,current或end中的一个。start是默认值:即偏移量是相对文件开始处计算。current是偏移量从当前访问位置计算。end是偏移量从文件尾开始计算。 tell fileId 返回fileId标识的文件的当前访问位置。
eof fileId 如果到达fileId标识的文件的末尾返回1,否则返回0。 文件访问 > 当前工作目录
TCL提供两个命令来管理当前工作目录:pwd和Cd。
pwd和UNIX下的pwd命令完全一样, 没有参数,返回当前目录的完整路径。
cd 命令也和UNIX命令也一样,使用一个参数,可以把工作目录改变为参数提供的目录。如果cd 没使用参数,UNIX下,会把工作目录变为启动TCL脚本的用户的工作目录,WINDOWS下会把工作目录变为windows操作系统的安装目录所在的盘的根目录(如:C:/)。值得注意的是,提供给cd的参数中路径中的应该用'/'而不是'\\'。如 cd C:/TCL/lib。这是UNIX的风格。 文件访问 > 文件操作和获取文件信息
TCL提供了两个命令进行文件名操作:glob和file,用来操作文件或获取文件信息。
glob命令采用一种或多种模式作为参数,并返回匹配这个(些)模式的所有文件的列表,其语法为: glob ?switches? pattern ?pattern ...? 其中switches可以取下面的值:
-nocomplain :允许返回一个空串,没有-nocomplain时,如果结果是空的,就返回错误。 -- :表示switches结束,即后面以'-'开头的参数将不作为switches。 glob命令的模式采用string match命令(见8.5.7节)的匹配规则。例如: %glob *.c *.h main.c hash.c hash.h
返回当前目录中所有.c或.h的文件名。 glob 还允许模式中包含' 括在花括号中间以逗号分开的多种选择',例如 : %glob {{src,backup}/*.[ch]}
src/main.c src/hash.c src/hash.h backup/hash.c 下面的命令和上面的命令等价: glob {src/*.[ch]} {backup/*.[ch]}
注意:这些例子中模式周围的花括号是必须的,可以防止命令置换。在调用glob命令对应的C过程前这些括号会被TCL解释器去掉。
如果glob的模式以一斜线结束,那将只匹配目录名。例如: glob */
只返回当前目录的所有子目录。
如果glob返回的文件名列表为空,通常会产生一个错误。但是glob的在样式参数之前的第一个参数是\的话,这时即使结果为空,glob也不会产生错误。
对文件名操作的第二个命令是file。file是有许多选项的常用命令,可以用来进行文件操作也可以检索文件信息。这节讨论与名字相关的选项,下一节描述其他选项。使用file命令时,我们会发现其中有很明显的UNIX痕迹。
file atime name 返回一个十进制的字符串,表示文件name最后被访问的时间。时间是以秒为单位从1970年1月1日12:00AM开始计算。如果文件name 不存在或查询不到访问时间就返回错误。例: % file atime license.txt 975945600
file copy ?-force? ?--? source target
file copy ?-force? ?--? source ?source ...? targetDir
这个命令把source中指明的文件或目录递归的拷贝到目的地址targetDir,只有当存在-force选项时,已经存在的文件才会被覆盖。试图覆盖一个非空的目录或以一个文件覆盖一个目录或以一个目录覆盖一个文件都会导致错误。--的含义和前面所说的一样。 file delete ?-force? ?--? pathname ?pathname ... ? 这个命令删除pathname指定的文件或目录,当指定了-force时,非空的目录也会被删除。即使没有指定-force,只读文件也会被删除。删除一个不存在的文件不会引发错误。
file dirname name 返回name中最后一个“/”前的所有字符;如果 name 不包含“/”,返回“.”;如果name 中最后一个“/”是第name的第一个字符,返回“/”。
file executable name 如果name对当前用户是可以执行的,就返回1,否则返回0。 file exists name 如果name存在于当前用户拥有搜索权限的目录下返回1,否则返回0。
file extension name 返回name中最后的“.”以后(包括这个小数点)的所有字符。如果name中没有“.”或最后斜线后没有“.”返回空字符。
file isdirectory name 如果name是目录返回1,否则返回0。 file isfile name 如果name是文件返回1,否则返回0。
file lstat name arrayName 除了利用lstat内核调用代理stat内核调用之外,和file stat命令一样,这意味着如果name是一个符号连接,那么这个命令返回的是这个符号连接的信息而不是这个符号连接指向的文件的信息。对于不支持符号连接的操作系统,这个命令和和file stat命令一样。
file mkdir dir ?dir ...? 这个命令和UNIX的mkdir命令类似,创建dir中指明的目录。如果dir已经存在,这个命令不作任何事情,也不返回错误。不过如果试图用一个目录覆盖已经存在的一个文件会导致错误。这个命令顺序处理各个参数,如果发生错误的话,马上退出。
file mtime name 返回十进制的字符串,表示文件name最后被修改的时间。时间是以秒为单位从1970年1月1日12:00AM开始计算。
file owned name 如果name被当前用户拥有,返回1,否则返回0。
file readable name 如果当前用户可对name进行读操作,返回1,否则返回0。
file readlink name 返回name代表的符号连接所指向的文件。如果name 不是符号连接或者找不到符号连接,返回错误。在不支持符号连接的操作系统(如windows)中选项readlink没有定义。 file rename ? -force? ?--? source target
file rename ?-force? ?--? source ?source ...? targetDir