如何Bash完成三部分模式

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

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

  1. $t [tab][tab] # shows options for first part
  2. walk run skip bike
  3. $t w[tab] # completes first part and appends delimiter
  4. $t walk_[tab][tab] # shows options for second part
  5. home work park
  6. $t walk_h[tab] # completes second part and appends delimiter
  7. $t walk_home_[tab][tab] # shows options for second part
  8. morning afternoon evening
  9. $t walk_home_a[tab] # completes second part and appends space
  10. $t walk_home_afternoon

我有这个代码

  1. _tool () {
  2. local cur="${COMP_WORDS[COMP_CWORD]}"
  3.  
  4. local first="walk run skip bike"
  5. local second="home work park"
  6. local third="morning afternoon evening"
  7.  
  8. case "${cur}" in
  9. *_*_*)
  10. COMPREPLY=( $(compgen -W "${third}" -- "") ); return 0;;
  11. *_*)
  12. COMPREPLY=( $(compgen -W "${second}" -S "_" -- ${cur}) ); compopt -o nospace; return 0;;
  13. *)
  14. COMPREPLY=( $(compgen -W "${first}" -S "_" -- ${cur}) ); compopt -o nospace; return 0;;
  15. esac
  16. }
  17.  
  18. complete -F _tool t

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

  1. $t [tab][tab]
  2. bike_ run_ skip_ walk_
  3. $t b[tab]
  4. $t bike_[tab][tab] # nothing but bells

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

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

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

  1. $t bike_[tab][tab]
  2. home_ park_ work_
  3. $t bike_h[tab][tab]
  4. home_ park_ work_
  5. $t bike_ho[tab][tab]
  6. home_ park_ work_

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

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

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

  1. $t bike_[tab][tab]
  2. bike_home_ bike_park_ bike_work_
  3. $t bike_ho[tab]
  4. $t bike_ # "ho" was erased

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

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

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

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

我能够创造出你想要的东西.请参阅我的代码
  1. _tool () {
  2. local cur="${COMP_WORDS[COMP_CWORD]}"
  3.  
  4. local first="walk run skip bike"
  5.  
  6. case "${cur}" in
  7. *_*_*)
  8. local firstsecond=`echo ${cur} | awk -F '_' '{print $1"_"$2}'`
  9. local third="${firstsecond}_morning ${firstsecond}_afternoon ${firstsecond}_evening"
  10. COMPREPLY=( $(compgen -W "${third}" -- ${cur}) ); return 0;;
  11. *_*)
  12. local firstcomp=`echo ${cur} | awk -F '_' '{print $1}'`
  13. local second="${firstcomp}_home ${firstcomp}_work ${firstcomp}_park"
  14. COMPREPLY=( $(compgen -W "${second}" -S "_" -- ${cur}) ); compopt -o nospace; return 0;;
  15. *)
  16. COMPREPLY=( $(compgen -W "${first}" -S "_" -- ${cur}) ); compopt -o nospace; return 0;;
  17. esac
  18. }
  19.  
  20. complete -F _tool t

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

  1. $t [tab][tab] # shows options for first part
  2. bike_ run_ skip_ walk_
  3. $t w[tab] # completes first part and appends delimiter
  4. $t walk_[tab][tab] # shows options for second part
  5. walk_home_ walk_park_ walk_work_
  6. $t walk_h[tab] # completes second part and appends delimiter
  7. $t walk_home_[tab][tab] # screws up with it
  8. $t walkhome_

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

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

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

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

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

猜你在找的Bash相关文章