0

我是新手,我正在尝试将 .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错了吗?或者也许是别的什么......

在此先感谢您的帮助!

4

2 回答 2

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
        }
    }
}
于 2013-03-21T01:17:40.820 回答
1

您将文件重命名了两次:一次在if命令中,另一次在 else 块中。您不需要file renameelse 块中的命令。

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
            }
        }
    }   
}
于 2013-03-20T23:43:28.633 回答