0

より正確には:

次のような内容のファイル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

何か助けはありますか?

4

4 に答える 4

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"}
}

正規表現には-allスイッチがありますが、-allで最後に一致する変数しか取得できないため、ここでは使用できないと思います。

于 2012-07-14T09:28:14.123 に答える
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
于 2012-07-14T15:21:37.617 に答える
0

この場合、私はawkに実行したくなるかもしれません:

set output [exec awk {$2 == "!!" {print $1, $3}} abc.txt]
puts $output
于 2012-07-14T18:55:58.970 に答える
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

gets2つの引数を持つコマンドは、読み取られた行の長さ、または-1失敗時を返します。通常のファイルの場合、失敗モードはEOFのみであるため、負の値を取得したときにループを終了できます。他の種類のチャネルはより複雑になる可能性があります… )。

于 2012-07-14T23:38:19.170 に答える