在文件中查找搜索字符串并使用这些行在TCL中进行处理

时间:2012-07-13 23:08:11

标签: tcl

更确切地说:

我需要查看一个文件abc.txt,其内容如下:

files/f1/atmp.c        98   100  

files/f1/atmp1.c       89   100 

files/f1/atmp2.c  !!   75   100

files/f2/btmp.c        92   100

files/f2/btmp2.c  !!   85   100

files/f3/xtmp.c        92   100

脚本需要找到“!!”并使用这些行打印出以下输出:

atmp2.c  75

btmp2.c  85

任何帮助?

4 个答案:

答案 0 :(得分:1)

这应该可以解决问题。

set data {files/f1/atmp.c        98   100  
files/f1/atmp1.c       89   100 
files/f1/atmp2.c  !!   75   100
files/f2/btmp.c        92   100
files/f2/btmp2.c  !!   85   100
files/f3/xtmp.c        92   100}

set lines [split $data \n]
foreach line $lines {
  set match [regexp {(\S+)\s+!!\s+(\d+)} $line -> file num]
  if {$match} {puts "$file $num"}
}

虽然regexp有一个-all开关我觉得我们不能在这里使用它,因为我们只用-all

获得最后一个匹配变量

答案 1 :(得分:1)

如果您的文件不是很大,您可以将整个内容啜饮到内存中,将行拆分为TCL列表,然后遍历列表以查找匹配项。例如:

set fh [open foo]
set lines [read $fh]
close $fh

set lines [split $lines "\n"]
foreach line $lines {
    if { [regexp {.*/(\S+\.c)\s*!!\s*(\d+)} $line match file data] } {
        puts "$file $data"
    }
}

这将成功返回带有“!!”的行在他们中。使用您发布的语料库,结果如下:

atmp2.c 75
btmp2.c 85

答案 2 :(得分:0)

在这种情况下我可能会被诱惑去执行awk:

set output [exec awk {$2 == "!!" {print $1, $3}} abc.txt]
puts $output

答案 3 :(得分:0)

诀窍是将从文件中读取行的代码与检测匹配行的正则表达式相结合,并提取相关部分(使用regexp的一步过程)。唯一棘手的部分是确定完全用作正则表达式,以便你得到你想要的。我要猜测你是在/之后的文件名之后,那些文件名不包含空格,并且你所追求的数字是之后的第一个数字序列的全部双重感叹。 (其他格式是可能的,其中一些格式更容易用其他工具提取,例如scan。)这会给我们这样的东西:

set f [open abc.txt]
while {[gets $f line] >= 0} {
    if {[regexp {([^\s/]+)\s+!!\s+(\d+)} $line -> name value]} {
        # Or do whatever you want with these
        puts "$name $value"
    }
}
close $f

(带有两个参数的gets命令返回行读取的长度,或者失败时-1。对于普通文件,唯一的失败模式是EOF,所以我们可以当我们得到负值时,只需终止循环。其他类型的通道可能更复杂......)