如果文件存在,则tcl文件重命名并捕获错误

时间:2013-03-20 23:09:01

标签: file try-catch tcl rename

我是新手,我正在尝试将.skip扩展名附加到从TCL中的文件名列表中获取的某些文件中。如果fileName.skip文件已经存在,我想抓住错误,将自己的消息放在屏幕上,然后继续下一个文件。这是我正在使用的代码:

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吗?或者也许是别的......

提前感谢您的帮助!

2 个答案:

答案 0 :(得分: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
        }
    }
}

答案 1 :(得分:1)

您重命名了两次文件:一次在if命令,另一个在else块中。您不需要在else块中使用file rename命令。

catch命令的工作方式是:

  1. 执行代码块
  2. 如果执行失败,则返回1.如果成功,则返回0
  3. 所以,在你的背景下:

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