TCL正则表达式:如何使用多行?

时间:2015-11-21 12:06:40

标签: regex string tcl

我想逐行输出并运行一个正则表达式,根据返回的输出做一些工作。
整个字符串类似于:

dc.user  pts/0        Oct 27 19:52  old        22926 (10.204.62.41) session=ssh
dc.user  pts/1        Nov 19 15:29 00:27        5109 (10.204.62.41) session=ssh

现在我想检查每行中是否存在old,如果存在,我想获取第二列(pts / 0)。我不明白如何逐行检查。一旦我能够逐行收集输入,我就可以使用像*old*这样的正则表来检查是否存在旧的,但为此我需要逐行获取它。
我甚至尝试通过将上面给出的输出存储在一个字符串中来实现它,但这似乎也没有用。相同的代码是:

set output $expect_out(buffer)
set lines [split $output "\n"]
foreach ln $lines {
puts $ln
}

变量output具有正确的数据,但我没有获得具有上述代码的所有行。

已编辑

现在我能够以某种方式使用split命令进行行分隔,但在正则表达式中存在问题。请查看代码并帮助我解决问题。

set re {dc.dcnm\s+pts/(\d+)\s+\w+\s+\d+\s(\S+)\s+(\S+)\s+(\d+).*}
set i "NAME     LINE         TIME         IDLE          PID COMMENT
dc.dcnm  pts/0        Oct 27 19:52  old        22926 (10.204.62.41) session=ssh
dc.dcnm  pts/1        Nov 19 15:29 00:27        5109 (10.204.62.41) session=ssh"
set fields [split $i "\n"]
        foreach field $fields {
        if {[regexp $re $field a b c d e]}
        {   puts "Sub Match1: $b"
            puts "Sub Match2: $c"
            puts "Sub Match2: $d"
            }
        }

运行上面的代码时,我收到以下错误:

wrong # args: no script following "[regexp $re $field a b c d e]" argument
    while executing
"if {[regexp $re $field a b c d e]}"
    ("foreach" body line 2)
    invoked from within
"foreach field $fields {
        if {[regexp $re $field a b c d e]}
        {   puts "Sub Match1: $b"
            puts "Sub Match2: $c"
            put..."
    (file "main.tcl" line 13)

1 个答案:

答案 0 :(得分:2)

您可以逐行读取输入文件:

set pfi [open "file_name" "r"]
while {[gets $pfi row] >= 0} {
}
close $pfi

当您阅读该行时,您可以检查旧版是否在内:

set p [string first "old" $row]

p中,您将找到旧字符串的位置。所以,

if {$p >= 0} {
    # read the next row
    set n [gets $pfi row]
    ....
}

所以,把所有这些放在一起你有:

set pfi [open "file_name" "r"]
while {[gets $pfi row] >= 0} {

    set p [string first "old" $row]    
    if {$p >= 0} {
        # read the next row
        set n [gets $pfi row]
    }
    # execute what you like with row where old is not present
    ....
}
close $pfi