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

最初のを見つけたらtest1(外側のループを使用して)行の処理を停止するか、少なくとも興味深い行の最初のロードが失われないように、追加モードで開きます。breakPar4

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

入力で最初のファイルに遭遇したときに出力ファイルを開き、最初のファイルPar1を読み取ったときにファイルを閉じますPar4。ここまでは順調ですね。ただし、2番目に到達したら、出力ファイルを読み続けて再度開きますPar1。それは出力ファイルを上書きします!

だから私の推測では、最初のものを見つけた後、入力を読むのをやめたいと思いますよねPar4

于 2012-07-26T09:59:52.880 に答える
2

whileループを次のように制御する必要はありません:http eof//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 に答える