从TCL中的glob函数结果中删除元素

时间:2013-10-09 19:05:10

标签: tcl

我在做:

glob -nocomplain *

因此我得到4个文件:

a b c d

如何从列表b中删除? 我正在使用这个功能:

 proc lremove {args} {
     if {[llength $args] < 2} {
        puts stderr {Wrong # args: should be "lremove ?-all? list pattern"}
     }
     set list [lindex $args end-1]
     set elements [lindex $args end]
     if [string match -all [lindex $args 0]] {
        foreach element $elements {
            set list [lsearch -all -inline -not -exact $list $element]
        }
     } else {
        # Using lreplace to truncate the list saves having to calculate
        # ranges or offsets from the indexed element. The trimming is
        # necessary in cases where the first or last element is the
        # indexed element.
        foreach element $elements {
            set idx [lsearch $list $element]
            set list [string trim \
                "[lreplace $list $idx end] [lreplace $list 0 $idx]"]
        }
     }
     return $list
 }

然而它不适用于glob结果,但仅适用于字符串。请帮忙。

1 个答案:

答案 0 :(得分:2)

那个lreplace程序相当狡猾,真的,交换顺序,贫民窟连接和string trim试图清理乱七八糟的东西。呸。这是一个更简单的版本(不支持-all,您不需要处理glob的输出,因为它通常是唯一元素的列表):

proc lremove {list args} {
    foreach toRemove $args {
        set index [lsearch -exact $list $toRemove]
        set list [lreplace $list $index $index]
    }
    return $list
}

我们来试试吧!

% lremove {a b c d e} b d f
a c e

从理论上讲,它可以提高效率,但需要做大量的工作才能成为PITA进行调试。这个版本更容易编写,显然是正确的。它应该比你正在使用的速度快得多,因为它坚持纯粹的列表操作。


来自glob的结果不应该特别特别,需要任何不寻常的努力才能与它们合作,但是有一些非常令人讨厌的历史错误使得并非总是如此。最新版本的8.4和8.5(即8.4.20和8.5.15)没有错误。也没有8.6(8.6.0或8.6.1)的任何发行版本。如果事情表现得很神秘,我们会开始询问版本并告诉你不要那么落后于时代......