iri*_*ava 2 zsh glob autocomplete
我正在尝试创建我的第一个zsh完成脚本,在本例中为命令netcfg.
Lame听起来可能听起来我已经陷入了第一道障碍,免责声明,我知道如何粗暴地做到这一点,但是我寻求"ZSH WAY"来做到这一点.
我需要在/ etc/networking中列出文件,但只列出文件,而不是目录组件,所以我做了以下操作.
echo $(ls /etc/network.d/*(.))
/etc/network.d/ethernet-dhcp /etc/network.d/wireless-wpa-config
Run Code Online (Sandbox Code Playgroud)
我想要的是:
ethernet-dhcp wireless-wpa-config
Run Code Online (Sandbox Code Playgroud)
所以我试着(原谅我的天真):
echo ${(s/*\/)$(ls /etc/network.d/*(.))}
/etc/network.d/ethernet-dhcp /etc/network.d/wireless-wpa-config
Run Code Online (Sandbox Code Playgroud)
似乎这不起作用,我敢肯定必须有一些聪明的方法来做到这一点,分成一个数组并得到最后一部分,但正如我所说,我完全是noob在这.
任何建议都感激不尽.
一般说明:无需使用ls生成文件名.你也可以使用 echo some*glob.但是如果你想保护可能的嵌入式换行符,即使这是一个坏主意.下面的第一个示例直接进入数组以保护嵌入式换行符.第二个使用printf生成NUL终止数据,以便在不使用变量的情况下完成相同的操作.
如果您愿意使用变量,这很容易做到:
typeset -a entries
entries=(/etc/network.d/*(.)) # generate the list
echo ${entries#/etc/network.d/} # strip the prefix from each one
Run Code Online (Sandbox Code Playgroud)
你也可以在没有变量的情况下做到这一点,但是隔离单个条目的额外东西有点难看:
# From the inside, to the outside:
# * glob the entries
# * NUL terminate them into a single string
# * split at NUL
# * strip the prefix from each one
echo ${${(0)"$(printf '%s\0' /etc/network.d/*(.))"}#/etc/network.d/}
Run Code Online (Sandbox Code Playgroud)
或者,如果您打算使用子shell(即前面示例中的命令替换),只需cd到目录,这样它就不是glob扩展的一部分(另外,您不必重复目录名称):
echo ${(0)"$(cd /etc/network.d && printf '%s\0' *(.))"}
Run Code Online (Sandbox Code Playgroud)