我有一个文件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
我不认为这是我的错误!
答案 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