我需要编写一个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)存储在一个变量中,以便在脚本的其他部分中使用。

最佳答案

这里有一个(相当低级的)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]
文档:chancontinueforeachiflappendlindexllengthlmapopensetsplitstring,,

10-07 13:09
查看更多