【TCL】字符串操作与文件操作

TCL字符串操作


|---|
| |

字符串操作


TCL 把所有的输入都当作字符串看待,所以 TCL 提供了较强的字符串操作功能,TCL 中与字符串操作有关的命令 string、format、regexp、regsub、scan


format 和 scan


format 命令类似于 C 语言中的 print 命令,用于格式化输出一些内容。

语法

shell 复制代码
format formatstring ?vlue value...?

示例

shell 复制代码
%set name john 
John 
%set age 20 
20 
%set msg [format "%s is %d years old" $name $age] 
john is 20 years old 

puts [format "My name is ${name}, I'm ${age} years old."]

scan 命令的语法如下:

shell 复制代码
scan string format varName ?varName ...?

scan 命令可以认为是 format命令的逆,其功能类似于 C 语言中的 scanf 函数。它按 format 提供的格式分析 string 字符串,然后把结果存到变量 varName 中,注意除了空格和 TAB 键之外,string 和 format 中的字符和'%'必须匹配。

scan 命令的返回值是匹配的变量个数

示例

shell 复制代码
% scan "some 26 34" "some %d %d" a b 
2 
% set a 
26 
% set b 
34 
% scan "12.34.56.78" "%d.%d.%d.%d" c d e f 
4 
% puts [format "the value of c is %d,d is %d,e is %d ,f is %d" $c $d $e $f] 
the value of c is 12,d is 34,e is 56 ,f is 78 

formatscan 命令中使用的特殊符号的含义如下:

符号 含义
%s 普通字符串
%d 整数
%.2f 浮点数,2是小数点后两位
%c 字符
%o 八进制
%x 十六进制

regexp



resub



string


string 命令具有强大的操作字符串的功能,其中的 option 选项多达 20 个,部分常用的选用如下所述。


compare

shell 复制代码
string compare ?-nocase? ?-length int? string1 string2

把字符串 string1 和 string2 根据字典顺序进行比较,如果字符串相同则返回0,如果 str1 的顺序比 str2 靠前就返回 -1,对于其它情况返回1。

如果有 -length 参数,那么只比较前 int 个字符,如果 int 为负数,那么这个参数被忽略。

如果有 -nocase 参数,那么比较时不区分大小写。


equal

shell 复制代码
string equal ?-nocase? ?-length int? string1 string2 

把字符串 string1 和 string2 进行比较,如果两者相同,返回值为 1,否则返回 0。

其他参数和 string compare 相同


match

shell 复制代码
string match ?-nocase? pattern string

如果 pattern 匹配 string,那么返回 1,否则返回 0。

如果有 -nocase 参数,那么就不区分大小写.

在 pattern 中可以使用通配符:

  • * 匹配 string 中的任意长的任意字符串,包括空字符串.
  • ? 匹配 string 中任意单个字符
  • [chars] 匹配字符集合 chars 中给出的任意字符,其中可以使用 A-Z 这种形式
  • \x 匹配单个字符 x,使用\是为了让 x 可以为字符*、-、[、]

示例

shell 复制代码
% string match {a[b-f]cdef} abcdef  
1 
# 注意一定要用'{',否则 TCL 解释器会把 b-f 当作命令名,从而导致错误

index

shell 复制代码
string index ${srting} charIndex

返回字符串中第 charIndex 个字符(0-based)。charIndex 可以是下面的值:

整数 n : 字符串中第 n 个字符(0-based)
end : 最后一个字符
end-整数 n :倒数第 n 个字符。string index "abcd" end-1 返回字符'c'

如果 charIndex 小于 0,或者大于字符串 string 的长度,那么返回空。


range

shell 复制代码
string range ${srting} first last

返回字符串中从第 first 个到第 last 个字符的子字符串(0-based)。如果 first<0,那么first 被看作 0,如果 last 大于或等于字符串的长度,那么 last 被看作 end,如果 first 比 last大,那么返回空。


map

string map 是一个用于字符串替换的命令,它可以按照指定的映射关系替换字符串中的字符或子字符串。

shell 复制代码
string map {old1 new1 old2 new2 ...} string

该命令可以将 string 中所有出现的 old1 替换为 new1,old2 替换为 new2,依此类推。

默认情况下,区分大小写;未匹配到 old,则不会发生替换。

map 命令的替换是严格按顺序执行的,并且后续映射不会影响已替换的部分,如下所示:

shell 复制代码
# Example 1
set str "abc"
set new_str [string map {a 1 b 2 ab x} $str]
puts $new_str  ;# 输出: 12c(先替换 a→1,b→2,ab 未被匹配)

# Example 2
# 先替换 "a" 为 "b",再替换 "b" 为 "c"
set new_str [string map {a b b c} "aabb"]
puts $new_str  ;# 输出: bbcc(而非预期中的 cccc)

高级用法

① 动态生成映射列表

映射列表可以通过变量或表达式动态生成:

shell 复制代码
set replacements {a 1 b 2 c 3}
set str "a-b-c"
set new_str [string map $replacements $str]
puts $new_str  ;# 输出: 1-2-3

② 删除字符

将 new 设为空字符串可实现删除操作:

shell 复制代码
set str "Hello, 123 World!"
set new_str [string map {, "" " " ""} $str]
puts $new_str  ;# 输出: Hello123World!

|---|
| |

文件操作


TCL 提供了丰富的文件操作的命令。通过这些命令你可以对文件进行操作,以顺序或随机方式读写文件,检索系统保留的文件信息(如最后访问时间)。


基本读写操作


TCL 中使用 open 打开文件,其基本用法如下,其中 access 是文件的打开方式。

shell 复制代码
open file_name ?access?

文件的打开方式有如下几种:

选项 作用
r 只读方式打开,文件已经存在,(默认方式)
r+ 读写方式打开,文件必须已经存在
w 只写方式打开文件,如果文件存在则清空文件内容,否则创建一个新的空文件
w+ 读写方式打开文件,如果文件存在则清空文件内容,否则创建一个新的空文件
a 只写方式打开文件,文件必须存在,并把指针指向文件结尾(追加)
a+ 只读方式打开,并把指针指向文件尾。如果文件不存在,创建新的空文件

open 命令返回一个字符串用于表示打开的文件,所以真正的文件打开方式为如下,其中 fileID 是文件标识符。

shell 复制代码
set fileID [open filename r]

当调用别的命令(gets,puts,close)对打开的文件进行操作时,就可以使用这个文件标识符。

TCL 有三个特定的文件标识:stdin,stdout,stderr,分别对应标准输入、标准输出和错误通道,任何时候都可以使用这三个文件标识。

TCL 中使用 getsread 命令读取文件内容,使用 puts 命令进行写文件操作。

默认文件输入输出方式是连续的:即每个 getsread 命令返回的是上次 getsread 访问位置后面的字节,每个 puts 命令写数据是接着上次 puts 写的位置接着写。

使用 open 命令打开文件,并完成相关操作之后,通常需要使用 close 命令关闭文件:

shell 复制代码
close ${fileID}

读文件:

gets 命令逐行读取文件,忽略行尾的换行符,其基本用法如下:

shell 复制代码
gets fileId ?varName?

fileId 是使用 open 命令打开文件时指定的文件标识符。

如果命令中有 varName 就把该行赋给它,并返回该行的字符数(文件尾返回-1);如果没有 varName 参数,返回文件的下一行作为命令结果(如果到了文件尾,就返回空字符串)

shell 复制代码
set f [open $filename r] 
while { [gets $f line ] } { 
	if {[regexp $pattern $line]} { 
		puts stdout $line 
	} 
	} 
close $f

写文件:

使用 puts 命令进行写文件操作,其基本用法如下:

shell 复制代码
puts ?-nonewline? ?fileId? string

puts 命令把 string 写到 fileId 中,如果没有 nonewline 选型,该命令会自动添加换行符,即每次写一行。

该命令的返回值为一空字符串。

puts 命令使用 C 的标准 I/O 库的缓冲区方案,这就意味着使用 puts 产生的信息不会立即出现在目标文件中。如果你想使数据立即出现在文件中,那你就调用 flush 命令:

shell 复制代码
flush fileId; # 把缓冲区内容写到 fileId 标识的文件中,命令返回值为空字符串。

文件查找


TCL 中 glob 命令用来对文件名进行操作,例如,glob *.c *.h 的作用是返回当前目录中所有以.c 或.h 为后缀的文件的名称。

基本语法:

glob 命令的基本语法如下:

shell 复制代码
glob ?options? pattern ?pattern ...?

常用选项:

选项 作用
-nocomplain 当没有匹配项时返回空列表。没有-nocomplain 时,如果结果是空的,就返回错误
-directory <dir> 指定搜索的基准目录
-types <type> 过滤文件类型(d=目录, f=普通文件, l=链接等)
-tails 返回相对于基准目录的文件名(需配合 -directory 使用)(只有文件名,没有路径)
-path 强制将 pattern 视为路径(处理包含 / 的复杂 pattern 时使用)
-- 标记选项结束,后续参数均为匹配 pattern(处理以 - 开头的文件名时使用)

示例1:判断文件是否存在

TCL 中有很多命令来判断一个文件是否存在。

方法1 :使用 file exists 命令

shell 复制代码
if { [file exists $filename] } {
	puts "文件存在"
} else {
	puts "文件不存在"
}

方法2 :使用 glob 命令

shell 复制代码
set files [glob -nocomplain $filename]
if { [llength $files] > 0 } {
	puts "文件存在"
} else {
	puts "文件不存在"
}
相关推荐
David.K25 天前
记录:win10环境手动编译tcl源码过程
windows·环境·win10·tcl·tcl环境搭建
闻道且行之3 个月前
FPGA|Quartus II 中使用TCL文件进行引脚一键分配
fpga开发·verilog·tcl
-曾牛4 个月前
PHP 与 MySQL 详解实战入门(1)
android·开发语言·mysql·渗透测试·php·php教程·脚本语言
monstercl8 个月前
Lua中基础函数使用详解
lua·脚本语言
x-cmd8 个月前
[250331] Paozhu 发布 1.9.0:C++ Web 框架,比肩脚本语言 | DeaDBeeF 播放器发布 1.10.0
android·linux·开发语言·c++·web·音乐播放器·脚本语言
weifexie9 个月前
perl、python、tcl语法中读写Excel的模块
linux·python·excel·perl·tcl
♢.*10 个月前
走进 Tcl 语言:历史、特性与应用
服务器·脚本语言·tcl·系统管理脚本
袁庭新1 年前
什么是Lua协同程序?和线程有什么区别?
java·开发语言·lua·脚本语言·袁庭新·什么是lua协同程序·lua协同程序
丰色木夕1 年前
Ubuntu下的tcl/tk编程快速入门
ubuntu·tcl·tk