2013-03-20 5 views
0

저는 초보자이며 TCL의 파일 이름 목록에서 가져온 일부 파일에 .skip 확장자를 추가하려고합니다. fileName.skip이있는 파일이 이미있는 경우 오류를 catch하고 화면에 내 메시지를 넣고 다음 파일을 계속 진행하고 싶습니다.파일 이름이 tcl 인 경우 파일 이름 바꾸기 및 캐칭 오류가 발생했습니다.

set i 0 
foreach fileName [glob -nocomplain -type f [file join $basedir *.wav]] { 
    foreach line $fileData { 
     if { [regexp $line $fileName] == 1 } { 
      if { [catch {file rename $fileName "$fileName.skip"}] } { 
       puts "Error skipping $fileName skipped file already exists" 
       continue 
      } else { 
       puts "Skipping $fileName..." 
       file rename [file join $basedir $fileName] [file join $basedir "$fileName.skip"] 
       incr i 
      } 
     } 
    } 
} 

이 난에 테스트하고있어 내 폴더에있는 세 개의 파일이 있습니다 : 여기에 내가 사용하고있는 코드는

test21.wav 
test21.wav.skip 
test22.wav 

이 코드는 이름을 변경 시점에 실행 (또는 이름을 변경하지 않습니다) 파일,하지만 그것은 화면이 출력 :

Error skipping C:/xxx/test21.wav file already exists 
Skipping C:/xxx/test22.wav... 
error renaming "C:/xxx/test22.wav": no such file or directory 
    while executing 
"file rename $fileName "$fileName.skip"" 

내가 스크립트가 작동하기 때문에이 오류에 대해 무엇인지 알아낼 수 없습니다. catch을 잘못 사용하고 있습니까? 아니면 다른 것일 수도 있습니다 ....

미리 도움을 청하십시오!

답변

1

파일의 이름을 두 번 변경했습니다. 한 번은 if 명령에서, 다른 하나는 else 블록에서 변경했습니다. else 블록에 file rename 명령이 필요하지 않습니다.

끝까지 catch 명령이 작동이가 : 실행이 실패하면

  1. 은, 코드
  2. 의 블록을 실행 1. 성공하면 반환에, 그래서 0

을 반환하여 컨텍스트 :

set i 0 
foreach fileName [glob -nocomplain -type f [file join $basedir *.wav]] { 
    foreach line $fileData { 
     if { [regexp $line $fileName] == 1 } { 
      if { [catch {file rename $fileName "$fileName.skip"}] } { 
       # Rename failed 
       puts "Error skipping $fileName skipped file already exists" 
      } else { 
       # Renamed OK 
       puts "Skipping $fileName..." 
       incr i 
      } 
     } 
    } 
} 
+0

죄송합니다. 나는 여전히 여기에 뭔가가 빠져 있다고 생각합니다 ... 'catch'명령이 실제로 내 명령을 실행합니까? 명령을 실행하지 않고 오류를 잡을 수있는 더 좋은 방법이 있습니까? 명령이 실행될 때만 카운터를 증가시킬 수 있습니까? – KaleidoEscape

+0

커맨드가 * ** 성공적으로 ** 실행 된 경우에만 * 카운터를 증가 시켰습니까? 당신은 이미 그것을 가지고 있습니다. else 블록에서 두 번째'파일 이름 변경 '을 제거하십시오. –

+0

알겠습니다. 도와 줘서 고마워! – KaleidoEscape

2

왜 처음 존재하는지 보지 않겠습니까?

set i 0 
foreach fileName [glob -nocomplain -type f [file join $basedir *.wav]] { 
    foreach line $fileData { 
     if {[regexp $line $fileName]} { 
      if {[file exists "$fileName.skip"]} { 
       puts "Error skipping $fileName -- skipped file already exists" 
       continue 
      } else { 
       puts "Skipping $fileName..." 
       set filepath [file join $basedir $fileName] 
       file rename $filepath $filepath.skip 
       incr i 
      } 
     } 
    } 
} 

$fileData 문자열의 목록이 포함되어 있음을 표시하기 때문에, 당신은 내부 foreach 루프가 필요하지 않습니다. lsearch이 여기에서 작동합니다 :

set i 0 
foreach fileName [glob -nocomplain -type f [file join $basedir *.wav]] { 
    if {[lsearch -regexp $fileData $fileName] != -1} { 
     if {[file exists "$fileName.skip"]} { 
      puts "Error skipping $fileName -- skipped file already exists" 
     } else { 
      puts "Skipping $fileName..." 
      set filepath [file join $basedir $fileName] 
      file rename $filepath $filepath.skip 
      incr i 
     } 
    } 
} 
+0

대단히 고맙습니다. 이것은 훌륭한 대답입니다. 내가하고 싶은 것보다 더 좋아 보이지만 ... 제 질문의 제목이'잡기 '라고 말한 이후에 다른 사람들이'catch '. – KaleidoEscape

관련 문제