博客 2014-11-20

这几天要用到expect ,顺便学习了一下TCL, 因为要在本机做算法就要用TCL,

如果在远程机做算法就只能在远程机执行,这样不安全...


1.字符串处理:

a.从字符串中获取字符 string index 和string range

$cat process.sh
 #! /usr/bin/tclsh
 set str1    "Have a lot of fun ..."
 puts [ string index $str1 2 ]
 puts [ string range $str1 2 3]
 
$tclsh  process.sh
v
ve

b. 长度 string length "stringsimple"

   大小写转换 string toupper /string tolower  "stringsimple"

   剪裁 string trim 、string trimleft、string trimright

       string trim aaxxxabad abc; 从左右开始,去掉字符串两边在“abc”中出现的任意字符,直到遇到不属于“abc”的字符为止。

       trimleft、trimright和trim类似,不过一个是去掉左边的,一个是去掉右这的

 简单搜索 string first/string last

       例 string first wh "I do not know where he is now."; 查找"wh"第一次出现的位置,结果是14。

       例 string last wh "I do not know where he is now. who ?"; 查找"wh"最后一次出现的位置,结果是31。

 判断字符串类型 string is 

       例 string is digit 125; 结果是1

 字符串合并 append 

mfleat@IQSZ-A0641 ~/bin
$ tclsh
% set e test
test
% append f $e ff
testff
% puts $f
testff
%


c.匹配 

 tcl有两种模式匹配, 一种是简单的"通配符"样式,一种是正则表达式


 string match实现了通配符样式的匹配

       string match a* Abc;结果为0,表示不匹配

       string match a* -nocase Abc;结果为1,表示匹配

 调用正则表达式匹配 regexp

       regexp {^[0-9]+$} 125sub330;"^+$"是从头到尾,这个语句检查字符串是否全部由数字组成。

 匹配并替换 regsub

        例 regsub there "they live there lives" their str; 第一个参数是正则表达式模式,第二个是待检测的字符串,与regexp相同,返回1代表匹配,

        0代表不匹配,但regsub还要将匹配的部分用第三个参数"their"替换,第四个参数str是一个变量,用来放替换后的字符串。


2. 字符串转int 用来计算

% set a 123 
123 
% set b 456 
456 
% puts $a+$b 
123+456 
% puts [expr $a+$b] 
579 
% puts [expr $a+$b] 
579


3. if else使用


set $b 3

if {$b==4} {

puts "good"

} elseif {$b==3} {

puts "YES"}


结果是YES


TCL 对于格式的要求蛮严格的,总结下

    . 条件判断的花括号和具体操作前面的花括号之间一定要有个空格

    . 具体操作单独一行

    . 具体操作之后的花括号另起一行,要和elseif 或 else 同一行,且中间隔个空格


4. 匹配执行命令

expect {
"*time*" { send "echo $TIMEFORMAT\r";sleep .1;send "export HISTTIMEFORMAT="%F %T "\r"; exp_continue}
"*have*" { send "echo $TIMEFORMAT\r";sleep .1;send "export HISTTIMEFORMAT="%F %T "\r"; exp_continue}
"*lot*"  { send "echo $TIMEFORMAT\r";sleep .1;send "export HISTTIMEFORMAT="%F %T "\r"; exp_continue}
"*fun*"  { send "echo $TIMEFORMAT\r";sleep .1;send "export HISTTIMEFORMAT="%F %T "\r";}
}


5.expect 可以精确到毫秒,就是0.01s,如果执行太快,可能连着打印命令,有一个好办法就是 sleep .3 就是等待0.3s


6. expect 调用本地shell 常量 


        set date [exec date "+%Y-%m-%d"] 


7. expect 发送远程shelll常量


       send "echo \$test"


8. expect 获取远程主机输出内容的一部分

expect -re "the number (a|b) is (\[0-9\]{1,3})" {
    set number1   $expect_out(1,string)
    set number1   $expect_out(2,string)
    set the_mached_string $expect_out(buffer)
}

$expect_out(1,string)可以将命中正则表达式中第一个括号(第一个分组)中的内容取出来;依此类推,$expect_out(2,string)可以取出第二个分组中的值。$expect_out(buffer)可以取出完整的被命中的字符串。


Expect -re  “a*”:后面是正则表达式,这时的*表示匹配0或者多次。就是可以匹配空字符串,a,aa,aaa……(可以用 .* 匹配所有)

Expect  “a*”       与上面的区别:默认是global pattern模式,相当于expect –gl“a*”,这时*表示任何一个字符。这时匹配aa,ab,ac……。