更确切地说:
我需要查看一个文件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
任何帮助?
答案 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,所以我们可以当我们得到负值时,只需终止循环。其他类型的通道可能更复杂......)