【问题标题】:tcl file rename and catching error if file existstcl 文件重命名并在文件存在时捕获错误
【发布时间】:2013-03-20 23:09:01
【问题描述】:

我是新手,我正在尝试将 .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?或者可能是别的什么......

提前感谢您的帮助!

【问题讨论】:

    标签: file try-catch tcl rename


    【解决方案1】:

    你为什么不先看看它是否存在?

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

    【讨论】:

    • 非常感谢,这是一个很好的答案,看起来更像我打算做的......但由于我的问题标题地址为catch,我将保留其他答案以防万一人们搜索有关catch 的内容。
    【解决方案2】:

    您两次重命名文件:一次在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
                }
            }
        }   
    }
    

    【讨论】:

    • 对不起,我想我还是遗漏了一些东西……catch 命令实际上确实执行了我的命令?有没有更好的方法可以在不执行命令的情况下捕获错误,以便只有在执行命令的情况下才能增加计数器?
    • 您的意思是仅在命令执行的情况下增加我的计数器 成功?你已经有了。只需删除 else 块中的第二个 file rename
    • 好的,我明白了。感谢您的帮助!
    猜你喜欢
    • 2020-05-29
    • 2020-12-04
    • 2013-05-19
    • 1970-01-01
    • 2013-08-25
    • 2012-03-06
    • 1970-01-01
    • 2011-08-16
    • 2018-06-05
    相关资源
    最近更新 更多