当我在

当我在

我试图将特定文件的列表存储到预期的变量中。

在我的脚本中,我尝试编译具有不同文件扩展名的文件,例如 .foo、.bar。

在此示例中,我有以下文件:

  • 某事.foo
  • 一些新的东西.foo
  • 不同的东西.bar
  • this_is_the_wrong_one.sh

为了仅获取 .foo 文件,我尝试运行以下命令:

set files "[exec ls -h | grep -E '\.foo' | rev | cut -c5- | rev]"
send_user "$files\n"

我期待看到:

  • 某物
  • 新鲜玩意

但是,我最终收到此错误消息:

子进程异常退出
    执行时
“exec ls -h | grep -E '\.foo' | rev | cut -c5- | rev”
    从内部调用
“设置文件”[exec ls -h | grep -E '\.foo' | grep -E '\.foo' |转 |切-c5- |转]""
    (文件“./runthis.sh”第 2 行)

我知道我可以使用find '*.foo'ls -h *.fooawk等。我注意到了这个模式... with find,如果我使用(单引号),那么预计会出现假发,所以这几乎消除了使用、、 和'的想法。如果我使用并且文件不存在,脚本将停止。它应该继续检查并列出其他文件。findawkgrepls -h *.foo

如果找到文件,最终将使用以下命令将其拆分为一个数组:

更新1:

set split_files "[split $files \n]"

答案1

问题是单引号对于 来说并不特殊tcl,因此您实际上是使用grep参数运行命令'\.foo',包括通常您希望由 shell 删除的引号。

这使得grep匹配失败,因此它以非零错误代码退出,因此命令exec会传递错误。

直接的答案是使用tcl双引号 ( grep -E "\\.foo") 或不使用引号 ( grep -E \\.foo) 或大括号引号 ( grep -E {\.foo})。但另一种选择是不诉诸 shell 命令。等价的tcl可能是:

set fullfiles [glob *.foo]
foreach f $fullfiles { lappend files [string trimright $f .foo] }

相关内容