1

我有一个文件 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

我没看到是我的错!

4

3 回答 3

2

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

当你找到你的 first 时,要么停止处理来自test1(通过外部循环)的行,要么以附加模式打开,这样至少第一批有趣的行不会丢失:breakPar4

set thefile2 [open test2 "a"]
于 2012-07-26T10:05:04.440 回答
2

你不想控制你的while循环eof: 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
于 2012-07-26T13:43:34.173 回答
2

当您Par1在输入中遇到第一个时打开输出文件,然后在读取第一个时关闭它Par4。到目前为止,一切都很好。但是当你到达第二个时,你只需继续阅读并重新打开输出文件Par1。这会覆盖输出文件!

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

于 2012-07-26T09:59:52.880 回答