如何Bash完成三部分模式

前端之家收集整理的这篇文章主要介绍了如何Bash完成三部分模式前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个命令行工具,它以三部分形式提供参数:
$t first_second_third

我有一组第一个有效值,一组有效值为秒,一组有效值为第三个.我想使用Bash完成功能来完成选项值的每个部分,如下例所示:

$t [tab][tab]           # shows options for first part
walk run skip bike
$t w[tab]               # completes first part and appends delimiter
$t walk_[tab][tab]      # shows options for second part
home work park
$t walk_h[tab]          # completes second part and appends delimiter
$t walk_home_[tab][tab] # shows options for second part
morning afternoon evening
$t walk_home_a[tab]     # completes second part and appends space
$t walk_home_afternoon

我有这个代码

_tool () {
  local cur="${COMP_WORDS[COMP_CWORD]}"

  local first="walk run skip bike"
  local second="home work park"
  local third="morning afternoon evening"

  case "${cur}" in
    *_*_*)
      COMPREPLY=( $(compgen -W "${third}" -- "") ); return 0;;
    *_*)
      COMPREPLY=( $(compgen -W "${second}" -S "_" -- ${cur}) ); compopt -o nospace; return 0;;
    *)
      COMPREPLY=( $(compgen -W "${first}" -S "_" -- ${cur}) ); compopt -o nospace; return 0;;
  esac
}

complete -F _tool t

第一句话很棒;没什么特别的但是第二个条款给了我没有选择或完成.

$t [tab][tab]
bike_  run_   skip_  walk_
$t b[tab]
$t bike_[tab][tab] # nothing but bells

我用以下代码替换了第二个子句(即在COMPREPLY调用中用空字符串替换了${cur}):

COMPREPLY=( $(compgen -W "${second}" -S "_" -- "") ); compopt -o nospace; return 0;;

我得到了命令行上所有选项的列表,但没有完成.

$t bike_[tab][tab]
home_  park_  work_
$t bike_h[tab][tab]
home_  park_  work_
$t bike_ho[tab][tab]
home_  park_  work_

我以为可能与${cur}和COMPREPLY单词列表有一些不好的交互,所以我再次更改了第二个子句,添加了一个与当前单词的第一部分相匹配的前缀:

local prefix=( $(expr "${cur}" : '\(.*_\)') )
COMPREPLY=( $(compgen -W "${second}" -P "${prefix}" -S "_" -- "") ); compopt -o nospace; return 0;;

这没有多大帮助在${cur}仍然在COMPREPLY命令中,我再也没有选择或完成.用一个空字符串代替,我得到了完整的选项(不只是curent部分).但是,按Tab键会清除打字的内容.

$t bike_[tab][tab]
bike_home_  bike_park_  bike_work_
$t bike_ho[tab]
$t bike_ # "ho" was erased

当然,我也有第三部分同样的问题.

>如何让Bash完成当前的单词,一部分?
>在选择选项之前,如何让Bash不附加分隔符?

这类似于another Bash complete question,但是我不想列出值的每个可能的排列,并且它们不被格式化为文件名(不知道文件名模式是否有所不同).

谢谢您的帮助!
留学美国相关考试

我能够创造出你想要的东西.请参阅我的代码
_tool () {
  local cur="${COMP_WORDS[COMP_CWORD]}"

  local first="walk run skip bike"

  case "${cur}" in
    *_*_*)
      local firstsecond=`echo ${cur} | awk -F '_' '{print $1"_"$2}'`
      local third="${firstsecond}_morning ${firstsecond}_afternoon ${firstsecond}_evening"
      COMPREPLY=( $(compgen -W "${third}" -- ${cur}) ); return 0;;
    *_*)
      local firstcomp=`echo ${cur} | awk -F '_' '{print $1}'`
      local second="${firstcomp}_home ${firstcomp}_work ${firstcomp}_park"
      COMPREPLY=( $(compgen -W "${second}" -S "_" -- ${cur}) ); compopt -o nospace; return 0;;
    *)
      COMPREPLY=( $(compgen -W "${first}" -S "_" -- ${cur}) ); compopt -o nospace; return 0;;
  esac
}

complete -F _tool t

我对自动完成不太熟悉,这是我第一次使用compgen或完整的,所以我不知道我可以回答你关于事物理论的问题.我可以告诉你我做了什么,以防它有助于你了解这个记录不全的功能如何工作.
首先,我试图了解你有什么我成功地转载了你的问题.那么我有这个想法,即使你不想在代码中自己列出每个排列,我可以使用局部变量来模仿,就像它有.我做的第一件事就是获得第一个下划线后的“第一个”元素,并将第二个元素添加到它,并将其提供给compgen.令我惊讶的是,它工作正常.然后我试图做同样的到第三级…然后问题开始.我发现第二部分没有像我想象的那样正常工作.完成第一个单词后,我会得到第二个的建议;选择一个字后,再按一下[TAB],第一个下划线就会消失.

$t [tab][tab]           # shows options for first part
bike_ run_ skip_ walk_
$t w[tab]               # completes first part and appends delimiter
$t walk_[tab][tab]      # shows options for second part
walk_home_ walk_park_ walk_work_
$t walk_h[tab]          # completes second part and appends delimiter
$t walk_home_[tab][tab] # screws up with it
$t walkhome_

我尝试将下划线移动到awk,没有成功:

local first=`echo ${cur} | awk -F '_' '{print $1"_"}'`
      local second="${first}home ${first}work ${first}park"

由于某种原因,我不得不将变量名称改为与“第一”不同的东西,并开始工作.然后,在第三个元素上,我有与上面描述的相同的问题,在第三个元素中输入的任何东西都会消失,但是[tab] [tab]会给出选项:

$t walk_home_[tab][tab] # shows options for second part
morning afternoon evening
$t walk_home_aft[tab]     # erases what I typed
$t walk_home_

我在第三个字中添加了${cur}到compgen,它的工作.这只是我做了什么的总结…但我有一个工作版本,所以我很高兴. 原文链接:/bash/385943.html

猜你在找的Bash相关文章