我需要编写一个tcl脚本来处理文本文件的行。该文件如下所示
10.77.33.247 10.77.33.241 rtp 0x26
10.77.33.247 10.77.33.241 rtp 0x26
10.77.33.247 10.77.33.241 rtp 0x26
10.77.33.247 10.77.33.241 0x24
10.77.33.247 10.77.33.241 0x22
10.77.33.247 10.77.33.241 0x21我需要能够遍历文件,对于包含rtp的每一行,将它后面的值(例如,上面示例中的0x26 )存储在一个变量中,以便在脚本的其他部分使用。
发布于 2015-05-06 22:46:32
下面是一种(相当低级的) Tcl方法。
set ch [open myfile.txt]
set data [chan read $ch]
chan close $ch
set lines [split [string trim $data] \n]
set res {}
foreach line $lines {
if {[llength $line] > 3 && [lindex $line 2] eq {rtp}} {
lappend res [lindex $line 3]
}
}如果将"myfile.txt“替换为数据文件的名称并运行此代码,您将获得在变量res中收集到的单词。
解释
通常最好使用标准(内置或tcllib)命令,比如glenn jackman的答案中的fileutil::foreachLine。然而,如果你想一步一步地做,Tcl仍然让它变得非常容易。
第一步是将文件的内容放入内存。这里也有一个标准的命令:fileutil::cat,但是下面的序列就可以了:
set ch [open myfile.txt]
set data [chan read $ch]
chan close $ch(这或多或少相当于set data [fileutil::cat myfile.txt]。)
下一步是将文本拆分成行。修剪文本两端的空格总是一个好主意,否则松散的换行符可能会创建空元素,从而干扰处理。
set lines [split [string trim $data] \n]在某些情况下,我们可能需要将行分割成字段列表,但从示例中可以看出,这些行似乎已经可以用作列表(只有空格、字母数字和行为良好的标点符号的行,比如通常的点)。
我们需要对匹配的行进行测试。有几种替代方案适合您提供的示例数据,包括
string match *rtp* $line ;# match every line that has "rtp" somewhere
[llength $line] > 3 ;# match every line that has more than three columns
[lindex $line 2] eq {rtp} ;# match every line where the third element is "rtp"我们还需要一种方法来提取我们想要的数据。如果"rtp“后面的单词总是在最后一列,那么[lindex $line end]将完成这项工作。如果单词始终在第四列,但可能还有其他列,则[lindex $line 3]更好。
抓取几个这样的备选方案,可以编写获取指定单词列表的过程
set res {}
foreach line $lines {
if {[llength $line] > 3 && [lindex $line 2] eq {rtp}} {
lappend res [lindex $line 3]
}
}(在伪代码中:获取一个空列表(res);测试每一行(使用上面两个测试的组合),从每一匹配行中提取需要的单词并将其添加到res列表中。)
或者,使用lmap (Tcl 8.6+)
set res [lmap line $lines {
if {[llength $line] > 3 && [lindex $line 2] eq {rtp}} {
lindex $line 3
} else {
continue
}
}]"rtp“单词后面的所有单词现在都应该在res中。如果你只是想要最后一场比赛,那就是[lindex $res end]。
文档:chan,continue,foreach,if,lappend,lindex,llength,lmap,open,<代码>C26,<代码>C27,<代码>C28
发布于 2015-05-06 20:27:15
假设您的文件是foo.txt:
grep "word" foo.txt发布于 2015-05-06 20:27:16
grep " 0x26“file.txt将显示所有包含0x26的行。
https://stackoverflow.com/questions/30076562
复制相似问题