2012-07-13 3 views
0

을 처리하는 라인을 사용 :파일에 검색 문자열을 찾고 더 정확하게는 TCL

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 
:

는이 같은 내용의 무언가가있는 abc.txt 파일에보고해야

스크립트가 "!!"을 찾아야합니다. 다음 행을 출력으로 출력하십시오.

atmp2.c 75 

btmp2.c 85 

어떤 도움이 필요합니까?

답변

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

정규 표현식은 - 모든 스위치가 있지만 나는 우리가 단지 파일이 큰없는 경우 마지막 일치 - 모든

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 
0

내가 AWK에 간부 인이 경우에 유혹 될 수 있습니다

set output [exec awk {$2 == "!!" {print $1, $3}} abc.txt] 
puts $output 
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 

(두 개의 인수를 가진 gets 명령은 라인 읽기의 길이를 반환합니다, 또는 -1 실패시. 일반 파일 유일한 실패 모드는 EOF이므로 음수 값을 얻으면 루프를 종료 할 수 있습니다. 다른 종류의 채널은 더 복잡 할 수 있습니다 ...)

관련 문제