bash 可编程完成文件名匹配模式的问题

bash 可编程完成文件名匹配模式的问题

我有一个名为 的简单命令th。我有一个 bash 完成文件,如下所示:

_th()  {
  COMPREPLY=()
  local curr=${COMP_WORDS[COMP_CWORD]}
  COMPREPLY=( $(compgen -f -X '!*.@(tar|tar.xz|tar.bz2|tar.gz|tbz|tgz)' -- "$curr") )
}                
complete -F _th -o filenames th

在大多数情况下,这可以按预期工作。对于我的th函数的参数,BASH 仅使用制表符完成以 , 结尾的文件.tartar.xz等两个问题:

  1. 匹配区分大小写。并非所有 tar 文件都有小写扩展名。 (在 bash-completion 文件中使用shoptsetnocaseglob不起作用。)

  2. 匹配会阻碍多字文件名,例如名称中带有空格的文件。

    [rsaw:blahb]$ ls
    bam.tgz  boom.TGZ  sad.TAR  spaces in this-file.tbz
    [rsaw:blahb]$ th<tabtab>
    bam.tgz        in             spaces         this-file.tbz  
    [rsaw:blahb]$ th spa<tabtab>
    in             spaces         this-file.tbz  
    [rsaw:blahb]$ th spaces<tabtab>   # At this point I added a backslash and pressed tab until 4 backslashes appeared
    in             spaces         this-file.tbz  
    [rsaw:blahb]$ th spaces\\\\<tabtab>   # At this point, nothing else happened 
    

任何帮助表示赞赏!

答案1

不确定这对您来说是否仍然是一个问题,但我在尝试完成中字文件名并对可能的解决方案有一些想法时遇到了类似的问题。

IFS通过添加local IFS=$'\n'修复了文件名中空格的问题来更改变量对我来说可能值得一试。

至于使事情不区分大小写,您可以$curr通过使用强制将 compgen 小写${cur,,}。两次更改后,完整功能将如下所示:

_th()  {
  local IFS=$'\n'
  local curr=${COMP_WORDS[COMP_CWORD]}
  COMPREPLY=( $(compgen -f -X '!*.@(tar|tar.xz|tar.bz2|tar.gz|tbz|tgz)' -- "${curr,,}") )
}                
complete -F _th -o filenames th

这将使整个文件名匹配不区分大小写。如果您只想扩展名不区分大小写,则可以进行一些字符串操作以$cur仅使扩展名小写。

答案2

您可以使用正则表达式对文件类型扩展名执行两件事。您可以将全大写扩展名直接添加到正则表达式中,即,(tar|TAR)或者您可以添加?i标志以使搜索不区分大小写。请参阅此指南:https://stackoverflow.com/questions/43632/can-you-make-just-part-of-a-regex-case-insensitive

那么,关于多词补全,这里有另一个答案:https://stackoverflow.com/questions/1146098/properly-handling-spaces-and-quotes-in-bash-completion (出于这个原因,我个人在所有文件中使用 _ 而不是空格)

相关内容