如何标记文件中的行?

时间:2012-07-26 09:51:58

标签: tcl

我有一个文件test1:

Par1  
Par2  
Par3  
Par4  
Par1  
Par5  
Par5  

我让这个Tcl来过滤它:

set thefile [open test1 "r"]
set is_Par1 0
set is_Par3 0
while {![eof $thefile]} {
    set line [gets $thefile]
    if { [regexp {Par1} $line] } {
            set thefile2 [open test2 "w"]
            set is_Par1 1
    }
    if { [regexp {Par3} $line] } {
            set is_Par3 1
            set is_Par1 0
    }
    if { $is_Par1 && !$is_Par3 } {
            puts $thefile2 $line
    }
    if { [regexp {Par4} $line] } {
            set is_Par3 0
            close $thefile2
    }
}
close $thefile

让我们假设文件和模式更复杂(我简化了它)

我有这个结果:

Par1
Par5
Par5

但我希望得到这样的结果:

Par1
Par2

我不认为这是我的错误!

3 个答案:

答案 0 :(得分:2)

当您在输入中遇到第一个Par1时打开输出文件,然后在阅读第一个Par4时将其关闭。到现在为止还挺好。但是当你到达第二个Par1时,你只需继续阅读并重新打开输出文件。那会覆盖输出文件!

所以我猜你想在找到第一个Par4之后停止阅读输入,对吗?

答案 1 :(得分:2)

问题是,您的代码在第一次看到test2时会打开Par1文件,写一些行,在看到Par4时关闭它,然后打开它再次下一次它在一个模式中看到Par1,使其在添加更多行之前将文件截断为零。 (当然,当脚本终止时,文件会自动关闭。)

当您找到第一个test1时,停止处理来自break的行(通过Par4外部循环),或者在追加模式下打开,以便至少第一次加载有趣的线条不会丢失:

set thefile2 [open test2 "a"]

答案 2 :(得分:2)

您不希望使用eof控制您的while循环:http://phaseit.net/claird/comp.lang.tcl/fmm.html#eof

假设您要在第一条Par1线开始打印并在Par4停止并排除所有Par3线:

set f_in [open test1 r]
set f_out [open test2 w]
set started false
while {[gets $f_in line] != -1} {
    if {[string first Par1 $line] != -1} {set started true}
    if {!$started} continue
    if {[string first Par3 $line] != -1} continue
    if {[string first Par4 $line] != -1} break
    puts $f_out $line
}
close $f_in
close $f_out